From 843ccb8048e0a6d6dcff8c7a4c479ed432af84bd Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Tue, 29 Jul 2025 15:15:34 +0200 Subject: [PATCH] deps: update grpc to 1.74.0 --- deps/grpc/.bazelci/presubmit.yml | 2 +- deps/grpc/Makefile | 55 +- deps/grpc/grpc.gyp | 29 +- .../grpc/create_channel_from_endpoint.h | 54 + deps/grpc/include/grpc/credentials.h | 16 +- .../include/grpc/event_engine/event_engine.h | 91 +- deps/grpc/include/grpc/grpc_posix.h | 21 +- .../include/grpc/impl/channel_arg_names.h | 6 +- deps/grpc/include/grpc/module.modulemap | 1 + deps/grpc/include/grpc/support/json.h | 24 + deps/grpc/include/grpcpp/channel.h | 6 + .../include/grpcpp/create_channel_posix.h | 34 + .../include/grpcpp/impl/generic_serialize.h | 15 +- .../include/grpcpp/security/credentials.h | 13 + .../include/grpcpp/support/callback_common.h | 19 +- .../include/grpcpp/support/client_callback.h | 10 +- deps/grpc/include/grpcpp/version_info.h | 6 +- deps/grpc/src/compiler/php_generator.cc | 3 +- deps/grpc/src/core/BUILD | 769 ++- deps/grpc/src/core/call/filter_fusion.h | 23 +- deps/grpc/src/core/call/interception_chain.h | 18 +- deps/grpc/src/core/channelz/channel_trace.cc | 328 +- deps/grpc/src/core/channelz/channel_trace.h | 466 +- deps/grpc/src/core/channelz/channelz.cc | 451 +- deps/grpc/src/core/channelz/channelz.h | 223 +- .../src/core/channelz/channelz_registry.cc | 3 +- .../src/core/channelz/channelz_registry.h | 24 + deps/grpc/src/core/channelz/property_list.cc | 357 ++ deps/grpc/src/core/channelz/property_list.h | 202 + .../grpc/src/core/channelz/ztrace_collector.h | 5 +- deps/grpc/src/core/channelz/zviz/data.cc | 139 + deps/grpc/src/core/channelz/zviz/data.h | 34 + deps/grpc/src/core/channelz/zviz/entity.cc | 51 + deps/grpc/src/core/channelz/zviz/entity.h | 29 + .../src/core/channelz/zviz/environment.cc | 32 + .../grpc/src/core/channelz/zviz/environment.h | 36 + deps/grpc/src/core/channelz/zviz/html.cc | 105 + deps/grpc/src/core/channelz/zviz/html.h | 103 + deps/grpc/src/core/channelz/zviz/layout.cc | 37 + deps/grpc/src/core/channelz/zviz/layout.h | 130 + .../src/core/channelz/zviz/layout_html.cc | 82 + .../grpc/src/core/channelz/zviz/layout_html.h | 61 + deps/grpc/src/core/channelz/zviz/strings.cc | 29 + deps/grpc/src/core/channelz/zviz/strings.h | 28 + deps/grpc/src/core/channelz/zviz/trace.cc | 36 + deps/grpc/src/core/channelz/zviz/trace.h | 31 + .../src/core/client_channel/client_channel.cc | 45 +- .../client_channel/client_channel_filter.cc | 48 +- .../src/core/client_channel/config_selector.h | 10 +- .../core/client_channel/dynamic_filters.cc | 11 +- .../src/core/client_channel/dynamic_filters.h | 2 +- .../client_channel/global_subchannel_pool.cc | 5 +- .../src/core/client_channel/retry_filter.cc | 48 +- .../src/core/client_channel/retry_filter.h | 17 +- .../retry_filter_legacy_call_data.cc | 10 +- .../retry_filter_legacy_call_data.h | 2 +- .../core/client_channel/retry_interceptor.cc | 74 +- .../core/client_channel/retry_interceptor.h | 35 +- .../src/core/client_channel/retry_throttle.cc | 107 +- .../src/core/client_channel/retry_throttle.h | 56 +- .../src/core/client_channel/subchannel.cc | 62 +- .../grpc/src/core/client_channel/subchannel.h | 8 + deps/grpc/src/core/config/config_vars.cc | 2 + deps/grpc/src/core/config/config_vars.yaml | 2 + .../src/core/config/core_configuration.cc | 1 + .../grpc/src/core/config/core_configuration.h | 11 + .../credentials/call/call_creds_registry.h | 125 + .../call/call_creds_registry_init.cc | 91 + ...cp_service_account_identity_credentials.cc | 54 +- .../jwt_token_file_call_credentials.cc | 86 + .../jwt_token_file_call_credentials.h | 74 + .../src/core/credentials/call/jwt_util.cc | 70 + .../grpc/src/core/credentials/call/jwt_util.h | 32 + .../transport/channel_creds_registry_init.cc | 2 +- .../google_default_credentials.cc | 76 +- .../transport/ssl/ssl_credentials.cc | 1 - .../tls/load_system_roots_supported.cc | 1 + .../transport/xds/xds_credentials.cc | 3 - .../gcp_authentication_filter.cc | 16 +- .../gcp_authentication_filter.h | 32 +- .../filters/http/client_authority_filter.cc | 6 +- .../message_compress/compression_filter.h | 47 +- .../filters/http/server/http_server_filter.h | 23 +- .../client/chaotic_good_connector.cc | 4 + .../chaotic_good/client_transport.cc | 33 +- .../transport/chaotic_good/client_transport.h | 4 +- .../core/ext/transport/chaotic_good/config.h | 7 + .../transport/chaotic_good/control_endpoint.h | 5 +- .../transport/chaotic_good/data_endpoints.cc | 1205 +++-- .../transport/chaotic_good/data_endpoints.h | 473 +- .../core/ext/transport/chaotic_good/frame.h | 11 + .../transport/chaotic_good/frame_transport.h | 4 + .../transport/chaotic_good/message_chunker.h | 10 +- .../ext/transport/chaotic_good/scheduler.cc | 569 ++ .../ext/transport/chaotic_good/scheduler.h | 68 + .../server/chaotic_good_server.cc | 211 +- .../chaotic_good/server/chaotic_good_server.h | 21 +- .../chaotic_good/server_transport.cc | 21 +- .../transport/chaotic_good/server_transport.h | 6 +- .../transport/chaotic_good/tcp_frame_header.h | 4 +- .../chaotic_good/tcp_frame_transport.cc | 48 +- .../chaotic_good/tcp_frame_transport.h | 8 +- .../chaotic_good/tcp_ztrace_collector.h | 126 +- .../chaotic_good_transport.h | 4 +- .../chaotic_good_legacy/client_transport.h | 4 +- .../server/chaotic_good_server.cc | 5 +- .../chaotic_good_legacy/server_transport.cc | 8 +- .../chaotic_good_legacy/server_transport.h | 18 +- .../chttp2/client/chttp2_connector.cc | 155 +- .../transport/chttp2/server/chttp2_server.cc | 11 +- .../chttp2/transport/chttp2_transport.cc | 277 +- .../chttp2/transport/chttp2_transport.h | 3 - .../transport/chttp2/transport/decode_huff.cc | 4753 +++++------------ .../transport/chttp2/transport/decode_huff.h | 2494 ++++----- .../transport/chttp2/transport/flow_control.h | 39 +- .../ext/transport/chttp2/transport/frame.cc | 10 + .../ext/transport/chttp2/transport/frame.h | 4 +- .../transport/chttp2/transport/frame_data.cc | 2 +- .../chttp2/transport/frame_settings.cc | 15 +- .../chttp2/transport/frame_window_update.cc | 9 +- .../chttp2/transport/header_assembler.h | 254 +- .../chttp2/transport/hpack_parser.cc | 2 +- .../chttp2/transport/hpack_parser_table.cc | 16 +- .../chttp2/transport/hpack_parser_table.h | 13 +- .../transport/http2_client_transport.cc | 814 ++- .../chttp2/transport/http2_client_transport.h | 268 +- .../transport/http2_server_transport.cc | 175 +- .../chttp2/transport/http2_server_transport.h | 13 +- .../chttp2/transport/http2_settings.h | 41 +- .../chttp2/transport/http2_stats_collector.cc | 30 + .../chttp2/transport/http2_stats_collector.h | 33 + .../transport/chttp2/transport/http2_status.h | 7 +- .../chttp2/transport/http2_transport.h | 8 +- .../chttp2/transport/http2_ztrace_collector.h | 29 - .../ext/transport/chttp2/transport/internal.h | 26 +- .../transport/chttp2/transport/keepalive.cc | 27 +- .../transport/chttp2/transport/keepalive.h | 27 +- .../chttp2/transport/message_assembler.h | 30 +- .../ext/transport/chttp2/transport/parsing.cc | 6 +- .../chttp2/transport/ping_callbacks.h | 19 + .../chttp2/transport/ping_promise.cc | 24 +- .../transport/chttp2/transport/ping_promise.h | 2 - .../chttp2/transport/ping_rate_policy.cc | 14 +- .../chttp2/transport/ping_rate_policy.h | 11 + .../chttp2/transport/stream_data_queue.h | 2 +- .../chttp2/transport/stream_lists.cc | 40 +- .../chttp2/transport/transport_common.cc | 19 + .../chttp2/transport/transport_common.h | 27 + .../ext/transport/chttp2/transport/writing.cc | 48 +- .../src/proto/grpc/channelz/v2/channelz.upb.h | 571 ++ .../grpc/channelz/v2/channelz.upb_minitable.c | 120 + .../grpc/channelz/v2/channelz.upb_minitable.h | 36 + .../src/proto/grpc/channelz/v2/promise.upb.h | 1272 +++++ .../grpc/channelz/v2/promise.upb_minitable.c | 312 ++ .../grpc/channelz/v2/promise.upb_minitable.h | 50 + .../grpc/channelz/v2/property_list.upb.h | 984 ++++ .../channelz/v2/property_list.upb_minitable.c | 226 + .../channelz/v2/property_list.upb_minitable.h | 44 + .../proto/grpc/channelz/v2/channelz.upbdefs.c | 80 + .../proto/grpc/channelz/v2/channelz.upbdefs.h | 47 + .../proto/grpc/channelz/v2/promise.upbdefs.c | 175 + .../proto/grpc/channelz/v2/promise.upbdefs.h | 82 + .../grpc/channelz/v2/property_list.upbdefs.c | 135 + .../grpc/channelz/v2/property_list.upbdefs.h | 67 + deps/grpc/src/core/filter/auth/auth_filters.h | 25 - .../core/filter/auth/client_auth_filter.cc | 118 - deps/grpc/src/core/filter/filter_args.h | 32 +- deps/grpc/src/core/handshaker/handshaker.cc | 37 +- deps/grpc/src/core/handshaker/handshaker.h | 3 + .../http_connect/http_connect_handshaker.cc | 4 +- .../security/legacy_secure_endpoint.cc | 11 +- .../handshaker/security/secure_endpoint.cc | 95 +- .../security/security_handshaker.cc | 5 +- .../tcp_connect/tcp_connect_handshaker.cc | 8 +- .../grpc/src/core/lib/channel/channel_args.cc | 15 + deps/grpc/src/core/lib/channel/channel_args.h | 3 + .../src/core/lib/channel/channel_stack.cc | 45 +- .../grpc/src/core/lib/channel/channel_stack.h | 16 +- .../lib/channel/channel_stack_builder_impl.cc | 2 +- .../lib/channel/channel_stack_builder_impl.h | 9 +- .../core/lib/channel/promise_based_filter.h | 10 +- deps/grpc/src/core/lib/debug/trace_impl.h | 1 - .../core/lib/event_engine/ares_resolver.cc | 211 +- .../src/core/lib/event_engine/ares_resolver.h | 50 +- .../lib/event_engine/cf_engine/cf_engine.cc | 4 +- .../lib/event_engine/cf_engine/cf_engine.h | 5 +- .../cf_engine/cfstream_endpoint.h | 8 +- .../endpoint_channel_arg_wrapper.cc | 40 + .../endpoint_channel_arg_wrapper.h | 60 + .../src/core/lib/event_engine/event_engine.cc | 7 + .../lib/event_engine/extensions/channelz.h | 16 +- .../src/core/lib/event_engine/forkable.cc | 105 - .../grpc/src/core/lib/event_engine/forkable.h | 67 - .../core/lib/event_engine/grpc_polled_fd.h | 5 + .../posix_engine/ev_epoll1_linux.cc | 292 +- .../posix_engine/ev_epoll1_linux.h | 26 +- .../posix_engine/ev_poll_posix.cc | 192 +- .../event_engine/posix_engine/ev_poll_posix.h | 16 +- .../event_engine/posix_engine/event_poller.h | 33 +- .../event_poller_posix_default.cc | 18 - .../file_descriptor_collection.cc | 124 + .../posix_engine/file_descriptor_collection.h | 243 + .../posix_engine/grpc_polled_fd_posix.h | 48 +- .../posix_engine/internal_errqueue.cc | 8 +- .../posix_engine/internal_errqueue.h | 7 +- .../posix_engine/posix_endpoint.cc | 237 +- .../posix_engine/posix_endpoint.h | 28 +- .../event_engine/posix_engine/posix_engine.cc | 449 +- .../event_engine/posix_engine/posix_engine.h | 79 +- .../posix_engine/posix_engine_listener.cc | 82 +- .../posix_engine/posix_engine_listener.h | 10 +- .../posix_engine_listener_utils.cc | 174 +- .../posix_engine_listener_utils.h | 11 +- .../posix_engine/posix_interface.h | 211 + .../posix_engine/posix_interface_posix.cc | 1083 ++++ .../posix_engine/posix_interface_windows.cc | 281 + .../posix_engine/posix_write_event_sink.cc | 154 + .../posix_engine/posix_write_event_sink.h | 174 + .../posix_engine/tcp_socket_utils.cc | 722 +-- .../posix_engine/tcp_socket_utils.h | 180 +- .../posix_engine/timer_manager.cc | 55 +- .../event_engine/posix_engine/timer_manager.h | 24 +- .../posix_engine/traced_buffer_list.cc | 268 +- .../posix_engine/traced_buffer_list.h | 120 +- .../posix_engine/wakeup_fd_eventfd.cc | 51 +- .../posix_engine/wakeup_fd_eventfd.h | 8 +- .../posix_engine/wakeup_fd_pipe.cc | 98 +- .../posix_engine/wakeup_fd_pipe.h | 8 +- .../posix_engine/wakeup_fd_posix.h | 13 +- .../posix_engine/wakeup_fd_posix_default.cc | 18 +- .../posix_engine/wakeup_fd_posix_default.h | 4 +- deps/grpc/src/core/lib/event_engine/shim.cc | 9 + deps/grpc/src/core/lib/event_engine/shim.h | 3 + .../event_engine/thread_pool/thread_pool.h | 10 +- .../thread_pool/thread_pool_factory.cc | 17 - .../thread_pool/work_stealing_thread_pool.cc | 6 +- .../thread_pool/work_stealing_thread_pool.h | 5 +- .../windows/grpc_polled_fd_windows.cc | 4 + .../windows/grpc_polled_fd_windows.h | 4 + .../event_engine/windows/windows_endpoint.h | 8 +- .../event_engine/windows/windows_engine.cc | 1 - .../lib/event_engine/windows/windows_engine.h | 4 +- .../event_engine/windows/windows_listener.cc | 16 +- .../src/core/lib/experiments/experiments.cc | 138 +- .../src/core/lib/experiments/experiments.h | 72 +- .../src/core/lib/experiments/experiments.yaml | 63 +- .../src/core/lib/experiments/rollouts.yaml | 10 +- deps/grpc/src/core/lib/iomgr/endpoint.cc | 7 +- deps/grpc/src/core/lib/iomgr/endpoint.h | 11 +- .../src/core/lib/iomgr/endpoint_cfstream.cc | 5 +- .../src/core/lib/iomgr/ev_epoll1_linux.cc | 9 +- deps/grpc/src/core/lib/iomgr/ev_poll_posix.cc | 9 +- .../lib/iomgr/event_engine_shims/endpoint.cc | 10 +- deps/grpc/src/core/lib/iomgr/python_util.h | 46 - deps/grpc/src/core/lib/iomgr/tcp_posix.cc | 18 +- deps/grpc/src/core/lib/iomgr/tcp_windows.cc | 5 +- deps/grpc/src/core/lib/promise/activity.h | 1 + .../grpc/src/core/lib/promise/arena_promise.h | 30 +- .../core/lib/promise/detail/promise_factory.h | 10 + .../core/lib/promise/detail/promise_like.h | 129 +- .../src/core/lib/promise/detail/seq_state.h | 1235 +++-- deps/grpc/src/core/lib/promise/if.h | 20 + .../core/lib/promise/inter_activity_mutex.h | 30 +- .../src/core/lib/promise/lock_based_mpsc.h | 306 ++ deps/grpc/src/core/lib/promise/loop.h | 68 +- deps/grpc/src/core/lib/promise/map.h | 24 + deps/grpc/src/core/lib/promise/mpsc.cc | 425 ++ deps/grpc/src/core/lib/promise/mpsc.h | 521 +- deps/grpc/src/core/lib/promise/party.cc | 51 +- deps/grpc/src/core/lib/promise/party.h | 67 +- deps/grpc/src/core/lib/promise/race.h | 31 + deps/grpc/src/core/lib/promise/seq.h | 5 +- deps/grpc/src/core/lib/promise/status_flag.h | 7 + deps/grpc/src/core/lib/promise/try_seq.h | 5 +- deps/grpc/src/core/lib/resource_quota/arena.h | 19 + deps/grpc/src/core/lib/slice/slice.h | 5 + .../src/core/lib/surface/channel_create.cc | 101 +- .../src/core/lib/surface/channel_create.h | 4 + .../grpc/src/core/lib/surface/channel_init.cc | 211 +- deps/grpc/src/core/lib/surface/channel_init.h | 65 +- .../src/core/lib/surface/filter_stack_call.cc | 27 +- deps/grpc/src/core/lib/surface/init.cc | 21 +- .../src/core/lib/surface/legacy_channel.cc | 8 +- .../src/core/lib/surface/legacy_channel.h | 4 +- deps/grpc/src/core/lib/surface/version.cc | 4 +- .../core/lib/transport/promise_endpoint.cc | 2 + .../src/core/lib/transport/promise_endpoint.h | 5 +- .../load_balancing/child_policy_handler.cc | 6 +- .../core/load_balancing/delegating_helper.h | 5 +- .../load_balancing/health_check_client.cc | 6 +- deps/grpc/src/core/load_balancing/lb_policy.h | 4 +- .../core/load_balancing/oob_backend_metric.cc | 6 +- .../load_balancing/pick_first/pick_first.cc | 3 + deps/grpc/src/core/load_balancing/xds/cds.cc | 11 +- .../grpc_plugin_registry_extra.cc | 2 + deps/grpc/src/core/resolver/xds/xds_config.cc | 9 +- deps/grpc/src/core/resolver/xds/xds_config.h | 13 +- .../resolver/xds/xds_dependency_manager.cc | 27 +- .../resolver/xds/xds_dependency_manager.h | 3 +- .../src/core/resolver/xds/xds_resolver.cc | 42 +- deps/grpc/src/core/server/server.cc | 95 +- deps/grpc/src/core/server/server.h | 23 +- .../core/server/xds_server_config_fetcher.cc | 88 +- .../src/core/service_config/service_config.h | 2 +- .../core/service_config/service_config_impl.h | 2 +- .../src/core/telemetry/context_list_entry.cc | 38 + .../src/core/telemetry/context_list_entry.h | 54 +- deps/grpc/src/core/telemetry/stats_data.cc | 440 +- deps/grpc/src/core/telemetry/stats_data.h | 403 +- deps/grpc/src/core/telemetry/stats_data.yaml | 587 +- deps/grpc/src/core/telemetry/tcp_tracer.h | 2 +- .../alts_zero_copy_grpc_protector.cc | 14 +- .../src/core/tsi/fake_transport_security.cc | 17 + .../src/core/tsi/ssl_transport_security.cc | 2 + .../src/core/tsi/transport_security_grpc.cc | 8 + .../src/core/tsi/transport_security_grpc.h | 15 + deps/grpc/src/core/util/backoff.cc | 6 +- deps/grpc/src/core/util/backoff.h | 1 + deps/grpc/src/core/util/down_cast.h | 2 +- deps/grpc/src/core/util/function_signature.h | 16 +- .../grpc/src/core/util/http_client/httpcli.cc | 17 +- deps/grpc/src/core/util/http_client/httpcli.h | 5 +- deps/grpc/src/core/util/latent_see.h | 13 +- deps/grpc/src/core/util/log.cc | 4 + deps/grpc/src/core/util/memory_usage.h | 268 + deps/grpc/src/core/util/per_cpu.cc | 2 + deps/grpc/src/core/util/per_cpu.h | 7 + deps/grpc/src/core/util/shared_bit_gen.h | 20 + deps/grpc/src/core/util/single_set_ptr.h | 4 +- deps/grpc/src/core/util/upb_utils.h | 42 + deps/grpc/src/core/util/uri.cc | 5 +- deps/grpc/src/core/util/useful.h | 55 +- .../src/core/util/wait_for_single_owner.cc | 31 + .../src/core/util/wait_for_single_owner.h | 24 + .../src/core/xds/grpc/xds_bootstrap_grpc.cc | 2 + .../src/core/xds/grpc/xds_bootstrap_grpc.h | 5 + .../grpc/src/core/xds/grpc/xds_client_grpc.cc | 8 +- .../core/xds/grpc/xds_common_types_parser.cc | 188 +- .../core/xds/grpc/xds_common_types_parser.h | 12 + deps/grpc/src/core/xds/grpc/xds_http_filter.h | 7 + .../xds/grpc/xds_http_gcp_authn_filter.cc | 22 + .../core/xds/grpc/xds_http_gcp_authn_filter.h | 3 + .../core/xds/grpc/xds_route_config_parser.cc | 53 +- .../grpc/src/core/xds/grpc/xds_server_grpc.cc | 76 +- deps/grpc/src/core/xds/grpc/xds_server_grpc.h | 12 +- .../core/xds/grpc/xds_server_grpc_interface.h | 4 + .../src/core/xds/grpc/xds_transport_grpc.cc | 18 + .../src/core/xds/xds_client/xds_bootstrap.h | 2 + .../src/core/xds/xds_client/xds_client.cc | 31 +- deps/grpc/src/cpp/README.md | 66 +- deps/grpc/src/cpp/client/channel_cc.cc | 7 + .../src/cpp/client/create_channel_posix.cc | 25 + .../grpc/src/cpp/client/secure_credentials.cc | 2 +- deps/grpc/src/cpp/ext/csm/BUILD | 4 +- .../src/cpp/ext/filters/census/rpc_encoding.h | 26 +- deps/grpc/src/cpp/ext/gcp/BUILD | 1 + .../src/cpp/ext/gcp/environment_autodetect.cc | 31 +- deps/grpc/src/cpp/ext/otel/BUILD | 1 + .../cpp/ext/otel/otel_client_call_tracer.cc | 177 +- .../cpp/ext/otel/otel_client_call_tracer.h | 35 +- deps/grpc/src/cpp/ext/otel/otel_plugin.cc | 44 +- deps/grpc/src/cpp/ext/otel/otel_plugin.h | 4 + .../cpp/ext/otel/otel_server_call_tracer.cc | 58 +- .../cpp/ext/otel/otel_server_call_tracer.h | 36 +- .../cpp/server/channelz/channelz_service.cc | 47 + .../cpp/server/channelz/channelz_service.h | 18 + .../channelz/channelz_service_plugin.cc | 20 +- deps/grpc/third_party/BUILD | 1 + deps/grpc/third_party/opencensus-cpp.patch | 146 + deps/grpc/third_party/protobuf.patch | 2 +- .../rake_aarch64-linux-gnu.current_version | 1 + .../Dockerfile | 3 +- .../rake_aarch64-linux-musl.current_version | 1 + .../Dockerfile | 5 +- .../rake_aarch64-linux.current_version | 1 - .../rake_x64-mingw32.current_version | 1 - .../rake_x86-linux-gnu.current_version | 1 + .../Dockerfile | 3 +- .../rake_x86-linux-musl.current_version | 1 + .../Dockerfile | 3 +- .../rake_x86-linux.current_version | 1 - .../rake_x86_64-linux-gnu.current_version | 1 + .../rake_x86_64-linux-gnu/Dockerfile | 16 + .../rake_x86_64-linux-musl.current_version | 1 + .../rake_x86_64-linux-musl/Dockerfile | 16 + .../rake_x86_64-linux.current_version | 1 - .../third_party/upb/upb/conformance/BUILD | 8 +- deps/grpc/third_party/upb/upb/hash/BUILD | 6 +- deps/grpc/third_party/upb/upb/io/BUILD | 20 +- deps/grpc/third_party/upb/upb/json/BUILD | 12 +- deps/grpc/third_party/upb/upb/message/BUILD | 60 +- .../third_party/upb/upb/mini_descriptor/BUILD | 10 +- .../grpc/third_party/upb/upb/mini_table/BUILD | 12 +- .../grpc/third_party/upb/upb/reflection/BUILD | 14 +- deps/grpc/third_party/upb/upb/test/BUILD | 20 +- deps/grpc/third_party/upb/upb/text/BUILD | 10 +- deps/grpc/third_party/upb/upb/util/BUILD | 20 +- deps/grpc/third_party/upb/upb/wire/BUILD | 14 +- 398 files changed, 24441 insertions(+), 12368 deletions(-) create mode 100644 deps/grpc/include/grpc/create_channel_from_endpoint.h create mode 100644 deps/grpc/src/core/channelz/property_list.cc create mode 100644 deps/grpc/src/core/channelz/property_list.h create mode 100644 deps/grpc/src/core/channelz/zviz/data.cc create mode 100644 deps/grpc/src/core/channelz/zviz/data.h create mode 100644 deps/grpc/src/core/channelz/zviz/entity.cc create mode 100644 deps/grpc/src/core/channelz/zviz/entity.h create mode 100644 deps/grpc/src/core/channelz/zviz/environment.cc create mode 100644 deps/grpc/src/core/channelz/zviz/environment.h create mode 100644 deps/grpc/src/core/channelz/zviz/html.cc create mode 100644 deps/grpc/src/core/channelz/zviz/html.h create mode 100644 deps/grpc/src/core/channelz/zviz/layout.cc create mode 100644 deps/grpc/src/core/channelz/zviz/layout.h create mode 100644 deps/grpc/src/core/channelz/zviz/layout_html.cc create mode 100644 deps/grpc/src/core/channelz/zviz/layout_html.h create mode 100644 deps/grpc/src/core/channelz/zviz/strings.cc create mode 100644 deps/grpc/src/core/channelz/zviz/strings.h create mode 100644 deps/grpc/src/core/channelz/zviz/trace.cc create mode 100644 deps/grpc/src/core/channelz/zviz/trace.h create mode 100644 deps/grpc/src/core/credentials/call/call_creds_registry.h create mode 100644 deps/grpc/src/core/credentials/call/call_creds_registry_init.cc create mode 100644 deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc create mode 100644 deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h create mode 100644 deps/grpc/src/core/credentials/call/jwt_util.cc create mode 100644 deps/grpc/src/core/credentials/call/jwt_util.h create mode 100644 deps/grpc/src/core/ext/transport/chaotic_good/scheduler.cc create mode 100644 deps/grpc/src/core/ext/transport/chaotic_good/scheduler.h create mode 100644 deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.cc create mode 100644 deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.h create mode 100644 deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.cc create mode 100644 deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.h create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c create mode 100644 deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h create mode 100644 deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.c create mode 100644 deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.h create mode 100644 deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c create mode 100644 deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h create mode 100644 deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c create mode 100644 deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h create mode 100644 deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc create mode 100644 deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h delete mode 100644 deps/grpc/src/core/lib/event_engine/forkable.cc delete mode 100644 deps/grpc/src/core/lib/event_engine/forkable.h create mode 100644 deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc create mode 100644 deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h create mode 100644 deps/grpc/src/core/lib/event_engine/posix_engine/posix_interface.h create mode 100644 deps/grpc/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc create mode 100644 deps/grpc/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc create mode 100644 deps/grpc/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc create mode 100644 deps/grpc/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h delete mode 100644 deps/grpc/src/core/lib/iomgr/python_util.h create mode 100644 deps/grpc/src/core/lib/promise/lock_based_mpsc.h create mode 100644 deps/grpc/src/core/lib/promise/mpsc.cc create mode 100644 deps/grpc/src/core/telemetry/context_list_entry.cc create mode 100644 deps/grpc/src/core/util/memory_usage.h create mode 100644 deps/grpc/src/core/util/wait_for_single_owner.cc create mode 100644 deps/grpc/third_party/opencensus-cpp.patch create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_aarch64-linux-gnu.current_version rename deps/grpc/third_party/rake-compiler-dock/{rake_aarch64-linux => rake_aarch64-linux-gnu}/Dockerfile (97%) create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_aarch64-linux-musl.current_version rename deps/grpc/third_party/rake-compiler-dock/{rake_x64-mingw32 => rake_aarch64-linux-musl}/Dockerfile (76%) delete mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_aarch64-linux.current_version delete mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x64-mingw32.current_version create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86-linux-gnu.current_version rename deps/grpc/third_party/rake-compiler-dock/{rake_x86-linux => rake_x86-linux-gnu}/Dockerfile (97%) create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86-linux-musl.current_version rename deps/grpc/third_party/rake-compiler-dock/{rake_x86_64-linux => rake_x86-linux-musl}/Dockerfile (97%) delete mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86-linux.current_version create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86_64-linux-gnu.current_version create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86_64-linux-gnu/Dockerfile create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86_64-linux-musl.current_version create mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86_64-linux-musl/Dockerfile delete mode 100644 deps/grpc/third_party/rake-compiler-dock/rake_x86_64-linux.current_version diff --git a/deps/grpc/.bazelci/presubmit.yml b/deps/grpc/.bazelci/presubmit.yml index fea3b6be721..40281c9889a 100644 --- a/deps/grpc/.bazelci/presubmit.yml +++ b/deps/grpc/.bazelci/presubmit.yml @@ -12,7 +12,7 @@ --- # TODO(yannic): Ideally, we should also enable buildifier and all platforms should test `//...`. tasks: - ubuntu2004: + ubuntu2204: build_targets: - //:all - //src/proto/... diff --git a/deps/grpc/Makefile b/deps/grpc/Makefile index 6f7492952f2..1166ab2dad3 100644 --- a/deps/grpc/Makefile +++ b/deps/grpc/Makefile @@ -77,7 +77,7 @@ CC_asan = clang CXX_asan = clang++ LD_asan = clang++ LDXX_asan = clang++ -CPPFLAGS_asan = -O0 -fsanitize-coverage=edge,trace-pc-guard -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS +CPPFLAGS_asan = -O0 -fsanitize-coverage=edge,trace-pc-guard -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument LDFLAGS_asan = -fsanitize=address VALID_CONFIG_asan-noleaks = 1 @@ -86,7 +86,7 @@ CC_asan-noleaks = clang CXX_asan-noleaks = clang++ LD_asan-noleaks = clang++ LDXX_asan-noleaks = clang++ -CPPFLAGS_asan-noleaks = -O0 -fsanitize-coverage=edge,trace-pc-guard -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS +CPPFLAGS_asan-noleaks = -O0 -fsanitize-coverage=edge,trace-pc-guard -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument LDFLAGS_asan-noleaks = fsanitize=address VALID_CONFIG_asan-trace-cmp = 1 @@ -95,7 +95,7 @@ CC_asan-trace-cmp = clang CXX_asan-trace-cmp = clang++ LD_asan-trace-cmp = clang++ LDXX_asan-trace-cmp = clang++ -CPPFLAGS_asan-trace-cmp = -O0 -fsanitize-coverage=edge,trace-pc-guard -fsanitize-coverage=trace-cmp -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS +CPPFLAGS_asan-trace-cmp = -O0 -fsanitize-coverage=edge,trace-pc-guard -fsanitize-coverage=trace-cmp -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument LDFLAGS_asan-trace-cmp = -fsanitize=address VALID_CONFIG_c++-compat = 1 @@ -156,7 +156,7 @@ CC_msan = clang CXX_msan = clang++ LD_msan = clang++ LDXX_msan = clang++ -CPPFLAGS_msan = -O0 -stdlib=libc++ -fsanitize-coverage=edge,trace-pc-guard -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-memory-use-after-dtor -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS +CPPFLAGS_msan = -O0 -stdlib=libc++ -fsanitize-coverage=edge,trace-pc-guard -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-memory-use-after-dtor -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie LDFLAGS_msan = -stdlib=libc++ -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,) DEFINES_msan = NDEBUG @@ -183,7 +183,7 @@ CC_tsan = clang CXX_tsan = clang++ LD_tsan = clang++ LDXX_tsan = clang++ -CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS +CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument LDFLAGS_tsan = -fsanitize=thread DEFINES_tsan = GRPC_TSAN @@ -194,7 +194,7 @@ CXX_ubsan = clang++ LD_ubsan = clang++ LDXX_ubsan = clang++ CPPFLAGS_ubsan = -O0 -stdlib=libc++ -fsanitize-coverage=edge,trace-pc-guard -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs -LDFLAGS_ubsan = -stdlib=libc++ -fsanitize=undefined,unsigned-integer-overflow +LDFLAGS_ubsan = -stdlib=libc++ -fsanitize=undefined DEFINES_ubsan = NDEBUG GRPC_UBSAN @@ -367,8 +367,8 @@ E = @echo Q = @ endif -CORE_VERSION = 48.0.0 -CPP_VERSION = 1.73.1 +CORE_VERSION = 49.0.0 +CPP_VERSION = 1.74.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) @@ -404,7 +404,7 @@ SHARED_EXT_CORE = dll SHARED_EXT_CPP = dll SHARED_PREFIX = -SHARED_VERSION_CORE = -48 +SHARED_VERSION_CORE = -49 SHARED_VERSION_CPP = -1 else ifeq ($(SYSTEM),Darwin) EXECUTABLE_SUFFIX = @@ -684,6 +684,7 @@ LIBGRPC_SRC = \ src/core/channelz/channel_trace.cc \ src/core/channelz/channelz.cc \ src/core/channelz/channelz_registry.cc \ + src/core/channelz/property_list.cc \ src/core/client_channel/backup_poller.cc \ src/core/client_channel/client_channel.cc \ src/core/client_channel/client_channel_factory.cc \ @@ -708,6 +709,7 @@ LIBGRPC_SRC = \ src/core/config/config_vars_non_generated.cc \ src/core/config/core_configuration.cc \ src/core/config/load_config.cc \ + src/core/credentials/call/call_creds_registry_init.cc \ src/core/credentials/call/call_creds_util.cc \ src/core/credentials/call/composite/composite_call_credentials.cc \ src/core/credentials/call/external/aws_external_account_credentials.cc \ @@ -721,6 +723,8 @@ LIBGRPC_SRC = \ src/core/credentials/call/jwt/json_token.cc \ src/core/credentials/call/jwt/jwt_credentials.cc \ src/core/credentials/call/jwt/jwt_verifier.cc \ + src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc \ + src/core/credentials/call/jwt_util.cc \ src/core/credentials/call/oauth2/oauth2_credentials.cc \ src/core/credentials/call/plugin/plugin_credentials.cc \ src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc \ @@ -803,13 +807,19 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/hpack_parse_result.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_parser_table.cc \ + src/core/ext/transport/chttp2/transport/http2_client_transport.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ + src/core/ext/transport/chttp2/transport/http2_stats_collector.cc \ + src/core/ext/transport/chttp2/transport/http2_transport.cc \ src/core/ext/transport/chttp2/transport/huffsyms.cc \ + src/core/ext/transport/chttp2/transport/keepalive.cc \ src/core/ext/transport/chttp2/transport/parsing.cc \ src/core/ext/transport/chttp2/transport/ping_abuse_policy.cc \ src/core/ext/transport/chttp2/transport/ping_callbacks.cc \ + src/core/ext/transport/chttp2/transport/ping_promise.cc \ src/core/ext/transport/chttp2/transport/ping_rate_policy.cc \ src/core/ext/transport/chttp2/transport/stream_lists.cc \ + src/core/ext/transport/chttp2/transport/transport_common.cc \ src/core/ext/transport/chttp2/transport/varint.cc \ src/core/ext/transport/chttp2/transport/write_size_policy.cc \ src/core/ext/transport/chttp2/transport/writing.cc \ @@ -943,6 +953,9 @@ LIBGRPC_SRC = \ src/core/ext/upb-gen/google/protobuf/timestamp.upb_minitable.c \ src/core/ext/upb-gen/google/protobuf/wrappers.upb_minitable.c \ src/core/ext/upb-gen/google/rpc/status.upb_minitable.c \ + src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c \ + src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c \ + src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c \ src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c \ src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c \ src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c \ @@ -1105,6 +1118,8 @@ LIBGRPC_SRC = \ src/core/ext/upbdefs-gen/google/protobuf/timestamp.upbdefs.c \ src/core/ext/upbdefs-gen/google/protobuf/wrappers.upbdefs.c \ src/core/ext/upbdefs-gen/google/rpc/status.upbdefs.c \ + src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c \ + src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c \ src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c \ src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.c \ src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.c \ @@ -1171,11 +1186,12 @@ LIBGRPC_SRC = \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/default_event_engine.cc \ src/core/lib/event_engine/default_event_engine_factory.cc \ + src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc \ src/core/lib/event_engine/event_engine.cc \ - src/core/lib/event_engine/forkable.cc \ src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc \ src/core/lib/event_engine/posix_engine/ev_poll_posix.cc \ src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc \ + src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc \ src/core/lib/event_engine/posix_engine/internal_errqueue.cc \ src/core/lib/event_engine/posix_engine/lockfree_event.cc \ src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc \ @@ -1183,6 +1199,9 @@ LIBGRPC_SRC = \ src/core/lib/event_engine/posix_engine/posix_engine.cc \ src/core/lib/event_engine/posix_engine/posix_engine_listener.cc \ src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc \ + src/core/lib/event_engine/posix_engine/posix_interface_posix.cc \ + src/core/lib/event_engine/posix_engine/posix_interface_windows.cc \ + src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc \ src/core/lib/event_engine/posix_engine/set_socket_dualstack.cc \ src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc \ src/core/lib/event_engine/posix_engine/timer.cc \ @@ -1285,8 +1304,10 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ src/core/lib/iomgr/wakeup_fd_posix.cc \ src/core/lib/promise/activity.cc \ + src/core/lib/promise/mpsc.cc \ src/core/lib/promise/party.cc \ src/core/lib/promise/sleep.cc \ + src/core/lib/promise/wait_set.cc \ src/core/lib/resource_quota/api.cc \ src/core/lib/resource_quota/arena.cc \ src/core/lib/resource_quota/connection_quota.cc \ @@ -1332,6 +1353,7 @@ LIBGRPC_SRC = \ src/core/lib/transport/call_final_info.cc \ src/core/lib/transport/connectivity_state.cc \ src/core/lib/transport/error_utils.cc \ + src/core/lib/transport/promise_endpoint.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/timeout_encoding.cc \ src/core/lib/transport/transport.cc \ @@ -1395,6 +1417,7 @@ LIBGRPC_SRC = \ src/core/service_config/service_config_impl.cc \ src/core/service_config/service_config_parser.cc \ src/core/telemetry/call_tracer.cc \ + src/core/telemetry/context_list_entry.cc \ src/core/telemetry/default_tcp_tracer.cc \ src/core/telemetry/histogram_view.cc \ src/core/telemetry/metrics.cc \ @@ -1491,6 +1514,7 @@ LIBGRPC_SRC = \ src/core/util/uri.cc \ src/core/util/uuid_v4.cc \ src/core/util/validation_errors.cc \ + src/core/util/wait_for_single_owner.cc \ src/core/util/windows/cpu.cc \ src/core/util/windows/directory_reader.cc \ src/core/util/windows/env.cc \ @@ -1593,13 +1617,12 @@ LIBGRPC_SRC = \ third_party/abseil-cpp/absl/log/internal/proto.cc \ third_party/abseil-cpp/absl/log/internal/structured_proto.cc \ third_party/abseil-cpp/absl/log/internal/vlog_config.cc \ - third_party/abseil-cpp/absl/log/log_entry.cc \ third_party/abseil-cpp/absl/log/log_sink.cc \ third_party/abseil-cpp/absl/numeric/int128.cc \ third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc \ third_party/abseil-cpp/absl/random/discrete_distribution.cc \ third_party/abseil-cpp/absl/random/gaussian_distribution.cc \ - third_party/abseil-cpp/absl/random/internal/pool_urbg.cc \ + third_party/abseil-cpp/absl/random/internal/entropy_pool.cc \ third_party/abseil-cpp/absl/random/internal/randen.cc \ third_party/abseil-cpp/absl/random/internal/randen_detect.cc \ third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc \ @@ -1616,7 +1639,6 @@ LIBGRPC_SRC = \ third_party/abseil-cpp/absl/strings/charconv.cc \ third_party/abseil-cpp/absl/strings/cord.cc \ third_party/abseil-cpp/absl/strings/cord_analysis.cc \ - third_party/abseil-cpp/absl/strings/cord_buffer.cc \ third_party/abseil-cpp/absl/strings/escaping.cc \ third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc \ third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc \ @@ -1677,8 +1699,6 @@ LIBGRPC_SRC = \ third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc \ third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc \ third_party/abseil-cpp/absl/time/time.cc \ - third_party/abseil-cpp/absl/types/bad_optional_access.cc \ - third_party/abseil-cpp/absl/types/bad_variant_access.cc \ third_party/address_sorting/address_sorting.c \ third_party/address_sorting/address_sorting_posix.c \ third_party/address_sorting/address_sorting_windows.c \ @@ -1764,6 +1784,7 @@ PUBLIC_HEADERS_C += \ include/grpc/byte_buffer_reader.h \ include/grpc/census.h \ include/grpc/compression.h \ + include/grpc/create_channel_from_endpoint.h \ include/grpc/credentials.h \ include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/event_engine.h \ @@ -1840,8 +1861,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_ ifeq ($(SYSTEM),Darwin) $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libcares.a $(OPENSSL_MERGE_LIBS) $(ZLIB_MERGE_LIBS) $(LDLIBS_SECURE) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.48 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libcares.a $(OPENSSL_MERGE_LIBS) $(ZLIB_MERGE_LIBS) $(LDLIBS_SECURE) $(LDLIBS) - $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.48 + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.49 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libcares.a $(OPENSSL_MERGE_LIBS) $(ZLIB_MERGE_LIBS) $(LDLIBS_SECURE) $(LDLIBS) + $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.49 $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so endif endif diff --git a/deps/grpc/grpc.gyp b/deps/grpc/grpc.gyp index 2c9b1b1c506..8cfc6c37e9d 100644 --- a/deps/grpc/grpc.gyp +++ b/deps/grpc/grpc.gyp @@ -147,6 +147,16 @@ 'src/core/channelz/channel_trace.cc', 'src/core/channelz/channelz.cc', 'src/core/channelz/channelz_registry.cc', + 'src/core/channelz/property_list.cc', + # 'src/core/channelz/zviz/data.cc', + # 'src/core/channelz/zviz/entity.cc', + # 'src/core/channelz/zviz/environment.cc', + # 'src/core/channelz/zviz/html.cc', + # 'src/core/channelz/zviz/layout.cc', + # 'src/core/channelz/zviz/layout_html.cc', + # 'src/core/channelz/zviz/strings.cc', + # 'src/core/channelz/zviz/trace.cc', + 'src/core/credentials/call/call_creds_registry_init.cc', 'src/core/credentials/call/call_creds_util.cc', 'src/core/credentials/call/json_util.cc', 'src/core/credentials/call/composite/composite_call_credentials.cc', @@ -165,6 +175,8 @@ 'src/core/credentials/call/jwt/json_token.cc', 'src/core/credentials/call/jwt/jwt_credentials.cc', 'src/core/credentials/call/jwt/jwt_verifier.cc', + 'src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc', + 'src/core/credentials/call/jwt_util.cc', 'src/core/credentials/call/oauth2/oauth2_credentials.cc', 'src/core/credentials/call/plugin/plugin_credentials.cc', 'src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc', @@ -248,7 +260,9 @@ 'src/core/ext/transport/chttp2/transport/hpack_parse_result.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser_table.cc', + 'src/core/ext/transport/chttp2/transport/http2_client_transport.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', + 'src/core/ext/transport/chttp2/transport/http2_stats_collector.cc', 'src/core/ext/transport/chttp2/transport/huffsyms.cc', 'src/core/ext/transport/chttp2/transport/keepalive.cc', 'src/core/ext/transport/chttp2/transport/parsing.cc', @@ -257,6 +271,7 @@ 'src/core/ext/transport/chttp2/transport/ping_promise.cc', 'src/core/ext/transport/chttp2/transport/ping_rate_policy.cc', 'src/core/ext/transport/chttp2/transport/stream_lists.cc', + 'src/core/ext/transport/chttp2/transport/transport_common.cc', 'src/core/ext/transport/chttp2/transport/varint.cc', 'src/core/ext/transport/chttp2/transport/write_size_policy.cc', 'src/core/ext/transport/chttp2/transport/writing.cc', @@ -388,6 +403,9 @@ 'src/core/ext/upb-gen/google/protobuf/timestamp.upb_minitable.c', 'src/core/ext/upb-gen/google/protobuf/wrappers.upb_minitable.c', 'src/core/ext/upb-gen/google/rpc/status.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c', 'src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c', 'src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c', 'src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c', @@ -550,6 +568,8 @@ 'src/core/ext/upbdefs-gen/google/protobuf/timestamp.upbdefs.c', 'src/core/ext/upbdefs-gen/google/protobuf/wrappers.upbdefs.c', 'src/core/ext/upbdefs-gen/google/rpc/status.upbdefs.c', + 'src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c', + 'src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c', 'src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c', 'src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.c', 'src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.c', @@ -613,8 +633,8 @@ 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/default_event_engine.cc', 'src/core/lib/event_engine/default_event_engine_factory.cc', + 'src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc', 'src/core/lib/event_engine/event_engine.cc', - 'src/core/lib/event_engine/forkable.cc', 'src/core/lib/event_engine/resolved_address.cc', 'src/core/lib/event_engine/shim.cc', 'src/core/lib/event_engine/slice.cc', @@ -693,6 +713,7 @@ 'src/core/lib/iomgr/wakeup_fd_pipe.cc', 'src/core/lib/iomgr/wakeup_fd_posix.cc', 'src/core/lib/promise/activity.cc', + 'src/core/lib/promise/mpsc.cc', 'src/core/lib/promise/party.cc', 'src/core/lib/promise/sleep.cc', 'src/core/lib/promise/wait_set.cc', @@ -744,6 +765,7 @@ 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc', 'src/core/lib/event_engine/posix_engine/ev_poll_posix.cc', 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', + 'src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc', 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', @@ -751,6 +773,9 @@ 'src/core/lib/event_engine/posix_engine/posix_engine.cc', 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', 'src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc', + 'src/core/lib/event_engine/posix_engine/posix_interface_posix.cc', + 'src/core/lib/event_engine/posix_engine/posix_interface_windows.cc', + 'src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc', 'src/core/lib/event_engine/posix_engine/set_socket_dualstack.cc', 'src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc', 'src/core/lib/event_engine/posix_engine/timer.cc', @@ -844,6 +869,7 @@ 'src/core/server/xds_channel_stack_modifier.cc', 'src/core/server/xds_server_config_fetcher.cc', 'src/core/telemetry/call_tracer.cc', + 'src/core/telemetry/context_list_entry.cc', 'src/core/telemetry/default_tcp_tracer.cc', 'src/core/telemetry/histogram_view.cc', 'src/core/telemetry/metrics.cc', @@ -942,6 +968,7 @@ 'src/core/util/uri.cc', 'src/core/util/uuid_v4.cc', 'src/core/util/validation_errors.cc', + 'src/core/util/wait_for_single_owner.cc', 'src/core/util/windows/cpu.cc', 'src/core/util/windows/directory_reader.cc', 'src/core/util/windows/env.cc', diff --git a/deps/grpc/include/grpc/create_channel_from_endpoint.h b/deps/grpc/include/grpc/create_channel_from_endpoint.h new file mode 100644 index 00000000000..e42d88df18f --- /dev/null +++ b/deps/grpc/include/grpc/create_channel_from_endpoint.h @@ -0,0 +1,54 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * 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. + * + */ + +#ifndef GRPC_CREATE_CHANNEL_FROM_ENDPOINT_H +#define GRPC_CREATE_CHANNEL_FROM_ENDPOINT_H + +#include +#include +#include +#include + +#ifdef __cplusplus +#include + +#include +namespace grpc_core::experimental { + +/** + * EXPERIMENTAL API - Subject to change + * + * This function creates a gRPC channel using a pre-established + * endpoint from the EventEngine. This API supports both secure and insecure + * channel credentials. + * + * \param endpoint A unique pointer to an EventEngine endpoint representing + * an established connection. + * \param creds The channel credentials used to secure the connection. + * \param args Optional channel arguments to configure the channel behavior. + */ +grpc_channel* CreateChannelFromEndpoint( + std::unique_ptr + endpoint, + grpc_channel_credentials* creds, const grpc_channel_args* args); + +} // namespace grpc_core::experimental + +#endif // __cplusplus + +#endif /* GRPC_CREATE_CHANNEL_FROM_ENDPOINT_H */ diff --git a/deps/grpc/include/grpc/credentials.h b/deps/grpc/include/grpc/credentials.h index 8875dd115b6..f4a614d7570 100644 --- a/deps/grpc/include/grpc/credentials.h +++ b/deps/grpc/include/grpc/credentials.h @@ -206,21 +206,27 @@ GRPCAPI void grpc_call_credentials_release(grpc_call_credentials* creds); this could result in an oauth2 token leak. The security level of the resulting connection is GRPC_PRIVACY_AND_INTEGRITY. - If specified, the supplied call credentials object will be attached to the - returned channel credentials object. The call_credentials object must remain + If specified, the supplied call credentials objects will be attached to the + returned channel credentials object. The call_credentials objects must remain valid throughout the lifetime of the returned grpc_channel_credentials - object. It is expected that the call credentials object was generated + object. It is expected that each call credentials object was generated according to the Application Default Credentials mechanism and asserts the identity of the default service account of the machine. Supplying any other sort of call credential will result in undefined behavior, up to and including the sudden and unexpected failure of RPCs. If nullptr is supplied, the returned channel credentials object will use a - call credentials object based on the Application Default Credentials + default call credentials object based on the Application Default Credentials mechanism. + + The caller may choose to create the default credential with a secondary alts + credentials object to attach to the channel for ALTS connections. If an alts + credentials object is specified, it will be used if the underlying channel + type is ALTS. */ GRPCAPI grpc_channel_credentials* grpc_google_default_credentials_create( - grpc_call_credentials* call_credentials); + grpc_call_credentials* call_creds_for_tls, + grpc_call_credentials* call_creds_for_alts); /** Server certificate config object holds the server's public certificates and associated private keys, as well as any CA certificates needed for client diff --git a/deps/grpc/include/grpc/event_engine/event_engine.h b/deps/grpc/include/grpc/event_engine/event_engine.h index 46ec9552e0d..d2c91ca5968 100644 --- a/deps/grpc/include/grpc/event_engine/event_engine.h +++ b/deps/grpc/include/grpc/event_engine/event_engine.h @@ -23,12 +23,17 @@ #include #include +#include #include +#include +#include +#include #include #include "absl/functional/any_invocable.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/types/span.h" // TODO(vigneshbabu): Define the Endpoint::Write metrics collection system // TODO(hork): remove all references to the factory methods. @@ -240,28 +245,40 @@ class EventEngine : public std::enable_shared_from_this, size_t key; int64_t value; }; + // It is the responsibility of the caller of WriteEventCallback to make sure + // that the corresponding endpoint is still valid. HINT: Do NOT offload + // callbacks onto the EventEngine or other threads. using WriteEventCallback = absl::AnyInvocable) const>; // A bitmask of the events that the caller is interested in. // Each bit corresponds to an entry in WriteEvent. using WriteEventSet = std::bitset(WriteEvent::kCount)>; + + // A set of metrics that the caller is interested in. + class MetricsSet { + public: + virtual ~MetricsSet() = default; + + virtual bool IsSet(size_t key) const = 0; + }; + // A sink to receive write events. // The requested metrics are the keys of the metrics that the caller is // interested in. The on_event callback will be called on each event // requested. class WriteEventSink final { public: - WriteEventSink(absl::Span requested_metrics, + WriteEventSink(std::shared_ptr requested_metrics, std::initializer_list requested_events, WriteEventCallback on_event) - : requested_metrics_(requested_metrics), + : requested_metrics_(std::move(requested_metrics)), on_event_(std::move(on_event)) { for (auto event : requested_events) { requested_events_mask_.set(static_cast(event)); } } - absl::Span requested_metrics() const { + const std::shared_ptr& requested_metrics() const { return requested_metrics_; } @@ -273,10 +290,12 @@ class EventEngine : public std::enable_shared_from_this, return requested_events_mask_; } + /// Takes the callback. Ownership is transferred. It is illegal to destroy + /// the endpoint before this callback is invoked. WriteEventCallback TakeEventCallback() { return std::move(on_event_); } private: - absl::Span requested_metrics_; + std::shared_ptr requested_metrics_; WriteEventSet requested_events_mask_; // The callback to be called on each event. WriteEventCallback on_event_; @@ -288,10 +307,28 @@ class EventEngine : public std::enable_shared_from_this, class WriteArgs final { public: WriteArgs() = default; + + ~WriteArgs(); + WriteArgs(const WriteArgs&) = delete; WriteArgs& operator=(const WriteArgs&) = delete; - WriteArgs(WriteArgs&&) = default; - WriteArgs& operator=(WriteArgs&&) = default; + + WriteArgs(WriteArgs&& other) noexcept + : metrics_sink_(std::move(other.metrics_sink_)), + google_specific_(other.google_specific_), + max_frame_size_(other.max_frame_size_) { + other.google_specific_ = nullptr; + } + + WriteArgs& operator=(WriteArgs&& other) noexcept { + if (this != &other) { + metrics_sink_ = std::move(other.metrics_sink_); + google_specific_ = other.google_specific_; + other.google_specific_ = nullptr; // Nullify source + max_frame_size_ = other.max_frame_size_; + } + return *this; + } // A sink to receive write events. std::optional TakeMetricsSink() { @@ -314,6 +351,10 @@ class EventEngine : public std::enable_shared_from_this, return google_specific_; } + void* TakeDeprecatedAndDiscouragedGoogleSpecificPointer() { + return std::exchange(google_specific_, nullptr); + } + void SetDeprecatedAndDiscouragedGoogleSpecificPointer(void* pointer) { google_specific_ = pointer; } @@ -333,6 +374,31 @@ class EventEngine : public std::enable_shared_from_this, void* google_specific_ = nullptr; int64_t max_frame_size_ = 1024 * 1024; }; + + class TelemetryInfo { + public: + virtual ~TelemetryInfo() = default; + + /// Returns the list of write metrics that the endpoint supports. + /// The keys are used to identify the metrics in the GetMetricName and + /// GetMetricKey APIs. The current value of the metric can be queried by + /// adding a WriteEventSink to the WriteArgs of a Write call. + virtual std::vector AllWriteMetrics() const = 0; + /// Returns the name of the write metric with the given key. + /// If the key is not found, returns std::nullopt. + virtual std::optional GetMetricName( + size_t key) const = 0; + /// Returns the key of the write metric with the given name. + /// If the name is not found, returns std::nullopt. + virtual std::optional GetMetricKey( + absl::string_view name) const = 0; + /// Returns a MetricsSet with all the keys from \a keys set. + virtual std::shared_ptr GetMetricsSet( + absl::Span keys) const = 0; + /// Returns a MetricsSet with all supported keys set. + virtual std::shared_ptr GetFullMetricsSet() const = 0; + }; + /// Writes data out on the connection. /// /// If the write succeeds immediately, it returns true and the @@ -359,17 +425,8 @@ class EventEngine : public std::enable_shared_from_this, /// values are expected to remain valid for the life of the Endpoint. virtual const ResolvedAddress& GetPeerAddress() const = 0; virtual const ResolvedAddress& GetLocalAddress() const = 0; - /// Returns the list of write metrics that the endpoint supports. - /// The keys are used to identify the metrics in the GetMetricName and - /// GetMetricKey APIs. The current value of the metric can be queried by - /// adding a WriteEventSink to the WriteArgs of a Write call. - virtual std::vector AllWriteMetrics() = 0; - /// Returns the name of the write metric with the given key. - /// If the key is not found, returns std::nullopt. - virtual std::optional GetMetricName(size_t key) = 0; - /// Returns the key of the write metric with the given name. - /// If the name is not found, returns std::nullopt. - virtual std::optional GetMetricKey(absl::string_view name) = 0; + + virtual std::shared_ptr GetTelemetryInfo() const = 0; }; /// Called when a new connection is established. diff --git a/deps/grpc/include/grpc/grpc_posix.h b/deps/grpc/include/grpc/grpc_posix.h index 864ba979a9e..a66489d540d 100644 --- a/deps/grpc/include/grpc/grpc_posix.h +++ b/deps/grpc/include/grpc/grpc_posix.h @@ -56,6 +56,25 @@ GRPCAPI void grpc_server_add_channel_from_fd(grpc_server* server, int fd, #ifdef __cplusplus } -#endif + +namespace grpc_core::experimental { + +/** + * EXPERIMENTAL API - Subject to change + * + * This function creates a gRPC channel using a raw file descriptor + * that represents an open socket. This API supports both secure and insecure + * channel credentials. + * + * \param fd The file descriptor representing the connection. + * \param creds The channel credentials used to secure the connection. + * \param args Optional channel arguments to configure the channel behavior. + */ +grpc_channel* CreateChannelFromFd(int fd, grpc_channel_credentials* creds, + const grpc_channel_args* args); + +} // namespace grpc_core::experimental + +#endif // __cplusplus #endif /* GRPC_GRPC_POSIX_H */ diff --git a/deps/grpc/include/grpc/impl/channel_arg_names.h b/deps/grpc/include/grpc/impl/channel_arg_names.h index 1fa7b637990..e1b5cf4bea6 100644 --- a/deps/grpc/include/grpc/impl/channel_arg_names.h +++ b/deps/grpc/include/grpc/impl/channel_arg_names.h @@ -123,10 +123,8 @@ /** Channel arg to override the http2 :scheme header. String valued. */ #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" /** How many pings can the client send before needing to send a data/header - frame? (0 indicates that an infinite number of pings can be sent without - sending a data frame or header frame). - If experiment "max_pings_wo_data_throttle" is enabled, instead of pings being - completely blocked, they are throttled. + frame, without being throttled? (0 indicates that an infinite number of pings + can be sent without sending a data frame or header frame). * Integer valued. Defaults to 2. */ #define GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA \ "grpc.http2.max_pings_without_data" diff --git a/deps/grpc/include/grpc/module.modulemap b/deps/grpc/include/grpc/module.modulemap index 30427e21d05..1e5174f6a60 100644 --- a/deps/grpc/include/grpc/module.modulemap +++ b/deps/grpc/include/grpc/module.modulemap @@ -6,6 +6,7 @@ header "byte_buffer.h" header "byte_buffer_reader.h" header "census.h" header "compression.h" + header "create_channel_from_endpoint.h" header "credentials.h" header "fork.h" header "grpc.h" diff --git a/deps/grpc/include/grpc/support/json.h b/deps/grpc/include/grpc/support/json.h index 764072090b4..5b98b1b6b4f 100644 --- a/deps/grpc/include/grpc/support/json.h +++ b/deps/grpc/include/grpc/support/json.h @@ -47,6 +47,30 @@ class Json { kArray, // Use array() for payload. }; + template + friend void AbslStringify(Sink& sink, Type type) { + switch (type) { + case Type::kNull: + sink.Append("null"); + break; + case Type::kBoolean: + sink.Append("boolean"); + break; + case Type::kNumber: + sink.Append("number"); + break; + case Type::kString: + sink.Append("string"); + break; + case Type::kObject: + sink.Append("object"); + break; + case Type::kArray: + sink.Append("array"); + break; + } + } + using Object = std::map; using Array = std::vector; diff --git a/deps/grpc/include/grpcpp/channel.h b/deps/grpc/include/grpcpp/channel.h index dacd27c38a4..37afaa0dc80 100644 --- a/deps/grpc/include/grpcpp/channel.h +++ b/deps/grpc/include/grpcpp/channel.h @@ -48,6 +48,11 @@ namespace experimental { /// TODO(roth): Once we see whether this proves useful, either create a gRFC /// and change this to be a method of the Channel class, or remove it. void ChannelResetConnectionBackoff(Channel* channel); + +/// Retrieves a channel's channelz uuid +/// TODO(ctiller): Once we see whether this proves useful, either create a gRFC +/// and change this to be a method of the Channel class, or remove it. +int64_t ChannelGetChannelzUuid(Channel* channel); } // namespace experimental /// Channels represent a connection to an endpoint. Created by \a CreateChannel. @@ -74,6 +79,7 @@ class Channel final : public grpc::ChannelInterface, friend class grpc::internal::BlockingUnaryCallImpl; friend class grpc::testing::ChannelTestPeer; friend void experimental::ChannelResetConnectionBackoff(Channel* channel); + friend int64_t experimental::ChannelGetChannelzUuid(Channel* channel); friend std::shared_ptr grpc::CreateChannelInternal( const std::string& host, grpc_channel* c_channel, std::vector #include #include #include @@ -61,10 +62,43 @@ CreateCustomInsecureChannelWithInterceptorsFromFd( std::unique_ptr> interceptor_creators); +/// Creates a new \a Channel from a file descriptor. +/// The channel target will be hard-coded to something like "ipv4:127.0.0.1:80". +/// The default authority will be "unknown", but the application can override it +/// using the GRPC_ARG_DEFAULT_AUTHORITY channel argument. +/// This API supports both secure and insecure channel credentials. +/// +/// \param fd The file descriptor representing the connection. +/// \param creds The channel credentials used to secure the connection. +/// \param args Channel arguments used to configure the channel behavior. +std::shared_ptr CreateChannelFromFd( + int fd, const std::shared_ptr& creds, + const ChannelArguments& args); + } // namespace experimental #endif // GPR_SUPPORT_CHANNELS_FROM_FD +namespace experimental { + +/// Creates a new \a Channel from an EventEngine endpoint. +/// The channel target will be hard-coded to something like "ipv4:127.0.0.1:80". +/// The default authority will be set to the endpoint's peer address, but the +/// application can override it using the GRPC_ARG_DEFAULT_AUTHORITY channel +/// argument. This API supports both secure and insecure channel credentials. +/// +/// \param endpoint A unique pointer to an EventEngine endpoint representing +/// an established connection. +/// \param creds The channel credentials used to secure the connection. +/// \param args Channel arguments used to configure the channel behavior. +std::shared_ptr CreateChannelFromEndpoint( + std::unique_ptr + endpoint, + const std::shared_ptr& creds, + const ChannelArguments& args); + +} // namespace experimental + } // namespace grpc #endif // GRPCPP_CREATE_CHANNEL_POSIX_H diff --git a/deps/grpc/include/grpcpp/impl/generic_serialize.h b/deps/grpc/include/grpcpp/impl/generic_serialize.h index 191b6465041..2efec89819d 100644 --- a/deps/grpc/include/grpcpp/impl/generic_serialize.h +++ b/deps/grpc/include/grpcpp/impl/generic_serialize.h @@ -26,9 +26,12 @@ #include #include +#include +#include #include #include "absl/log/absl_check.h" +#include "absl/strings/str_cat.h" /// This header provides serialization and deserialization between gRPC /// messages serialized using protobuf and the C++ objects they represent. @@ -44,8 +47,13 @@ Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb, "ProtoBufferWriter must be a subclass of " "::protobuf::io::ZeroCopyOutputStream"); *own_buffer = true; - int byte_size = static_cast(msg.ByteSizeLong()); - if (static_cast(byte_size) <= GRPC_SLICE_INLINED_SIZE) { + size_t byte_size = msg.ByteSizeLong(); + if (byte_size > std::numeric_limits::max()) { + return Status(StatusCode::INTERNAL, + "Protobuf is too large to be serialized", + absl::StrCat(byte_size, " bytes is beyond the limit 2^31-1")); + } + if (byte_size <= GRPC_SLICE_INLINED_SIZE) { Slice slice(byte_size); // We serialize directly into the allocated slices memory ABSL_CHECK(slice.end() == msg.SerializeWithCachedSizesToArray( @@ -55,7 +63,8 @@ Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb, return grpc::Status::OK; } - ProtoBufferWriter writer(bb, kProtoBufferWriterMaxBufferLength, byte_size); + ProtoBufferWriter writer(bb, kProtoBufferWriterMaxBufferLength, + static_cast(byte_size)); protobuf::io::CodedOutputStream cs(&writer); msg.SerializeWithCachedSizes(&cs); return !cs.HadError() diff --git a/deps/grpc/include/grpcpp/security/credentials.h b/deps/grpc/include/grpcpp/security/credentials.h index d3ff3c830d0..bd5f4ccfbef 100644 --- a/deps/grpc/include/grpcpp/security/credentials.h +++ b/deps/grpc/include/grpcpp/security/credentials.h @@ -19,8 +19,10 @@ #ifndef GRPCPP_SECURITY_CREDENTIALS_H #define GRPCPP_SECURITY_CREDENTIALS_H +#include #include #include +#include #include #include #include @@ -77,6 +79,17 @@ class ChannelCredentials : private grpc::internal::GrpcLibrary { grpc_channel_credentials* c_creds() { return c_creds_; } private: + friend std::shared_ptr + grpc::experimental::CreateChannelFromEndpoint( + std::unique_ptr + endpoint, + const std::shared_ptr& creds, + const ChannelArguments& args); +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + friend std::shared_ptr grpc::experimental::CreateChannelFromFd( + int fd, const std::shared_ptr& creds, + const ChannelArguments& args); +#endif // GPR_SUPPORT_CHANNELS_FROM_FD friend std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, diff --git a/deps/grpc/include/grpcpp/support/callback_common.h b/deps/grpc/include/grpcpp/support/callback_common.h index b4ba1e7baa5..bc4f1623d3b 100644 --- a/deps/grpc/include/grpcpp/support/callback_common.h +++ b/deps/grpc/include/grpcpp/support/callback_common.h @@ -83,7 +83,7 @@ class CallbackWithStatusTag : public grpc_completion_queue_functor { // there are no tests catching the compiler warning. static void operator delete(void*, void*) { ABSL_CHECK(false); } - CallbackWithStatusTag(grpc_call* call, std::function f, + CallbackWithStatusTag(grpc_call* call, std::function&& f, CompletionQueueTag* ops) : call_(call), func_(std::move(f)), ops_(ops) { grpc_call_ref(call); @@ -127,18 +127,17 @@ class CallbackWithStatusTag : public grpc_completion_queue_functor { auto status = std::move(status_); func_ = nullptr; // reset to clear this out for sure status_ = Status(); // reset to clear this out for sure - GetGlobalCallbackHook()->RunCallback( - call_, [func = std::move(func), status = std::move(status)]() { + GetGlobalCallbackHook()->RunCallback(call_, [&func, &status]() { #if GRPC_ALLOW_EXCEPTIONS - try { - func(status); - } catch (...) { - // nothing to return or change here, just don't crash the library - } + try { + func(status); + } catch (...) { + // nothing to return or change here, just don't crash the library + } #else // GRPC_ALLOW_EXCEPTIONS - func(status); + func(status); #endif // GRPC_ALLOW_EXCEPTIONS - }); + }); grpc_call_unref(call_); } }; diff --git a/deps/grpc/include/grpcpp/support/client_callback.h b/deps/grpc/include/grpcpp/support/client_callback.h index f3bdec9b16b..481e1c7e590 100644 --- a/deps/grpc/include/grpcpp/support/client_callback.h +++ b/deps/grpc/include/grpcpp/support/client_callback.h @@ -53,13 +53,13 @@ void CallbackUnaryCall(grpc::ChannelInterface* channel, const grpc::internal::RpcMethod& method, grpc::ClientContext* context, const InputMessage* request, OutputMessage* result, - std::function on_completion) { + std::function&& on_completion) { static_assert(std::is_base_of::value, "Invalid input message specification"); static_assert(std::is_base_of::value, "Invalid output message specification"); CallbackUnaryCallImpl x( - channel, method, context, request, result, on_completion); + channel, method, context, request, result, std::move(on_completion)); } template @@ -69,7 +69,7 @@ class CallbackUnaryCallImpl { const grpc::internal::RpcMethod& method, grpc::ClientContext* context, const InputMessage* request, OutputMessage* result, - std::function on_completion) { + std::function&& on_completion) { grpc::CompletionQueue* cq = channel->CallbackCQ(); ABSL_CHECK_NE(cq, nullptr); grpc::internal::Call call(channel->CreateCall(method, context, cq)); @@ -90,8 +90,8 @@ class CallbackUnaryCallImpl { auto* const alloced = static_cast(grpc_call_arena_alloc(call.call(), alloc_sz)); auto* ops = new (&alloced->opset) FullCallOpSet; - auto* tag = new (&alloced->tag) - grpc::internal::CallbackWithStatusTag(call.call(), on_completion, ops); + auto* tag = new (&alloced->tag) grpc::internal::CallbackWithStatusTag( + call.call(), std::move(on_completion), ops); // TODO(vjpai): Unify code with sync API as much as possible grpc::Status s = ops->SendMessagePtr(request); diff --git a/deps/grpc/include/grpcpp/version_info.h b/deps/grpc/include/grpcpp/version_info.h index df634203001..f48859926a1 100644 --- a/deps/grpc/include/grpcpp/version_info.h +++ b/deps/grpc/include/grpcpp/version_info.h @@ -19,9 +19,9 @@ #define GRPCPP_VERSION_INFO_H #define GRPC_CPP_VERSION_MAJOR 1 -#define GRPC_CPP_VERSION_MINOR 73 -#define GRPC_CPP_VERSION_PATCH 1 +#define GRPC_CPP_VERSION_MINOR 74 +#define GRPC_CPP_VERSION_PATCH 0 #define GRPC_CPP_VERSION_TAG "" -#define GRPC_CPP_VERSION_STRING "1.73.1" +#define GRPC_CPP_VERSION_STRING "1.74.0" #endif // GRPCPP_VERSION_INFO_H diff --git a/deps/grpc/src/compiler/php_generator.cc b/deps/grpc/src/compiler/php_generator.cc index 5d017122670..f591f99a3cf 100644 --- a/deps/grpc/src/compiler/php_generator.cc +++ b/deps/grpc/src/compiler/php_generator.cc @@ -108,7 +108,8 @@ void PrintMethod(const MethodDescriptor* method, Printer* out) { if (method->server_streaming()) { vars["return_type_id"] = "\\Grpc\\ServerStreamingCall"; } else { - vars["return_type_id"] = "\\Grpc\\UnaryCall"; + vars["return_type_id"] = + "\\Grpc\\UnaryCall<\\" + vars["output_type_id"] + ">"; } out->Print(vars, " * @param \\$input_type_id$ $$argument input argument\n" diff --git a/deps/grpc/src/core/BUILD b/deps/grpc/src/core/BUILD index 4d20b91ad1c..da365d2ec67 100644 --- a/deps/grpc/src/core/BUILD +++ b/deps/grpc/src/core/BUILD @@ -54,6 +54,11 @@ config_setting( values = {"define": "GRPC_MAXIMIZE_THREADYNESS=1"}, ) +config_setting( + name = "minimize_threadyness", + values = {"define": "GRPC_MINIMIZE_THREADYNESS=1"}, +) + grpc_cc_library( name = "channel_fwd", hdrs = [ @@ -84,6 +89,23 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "memory_usage", + hdrs = [ + "util/memory_usage.h", + ], + external_deps = [ + "absl/status", + "absl/status:statusor", + "absl/time", + "absl/strings:string_view", + "absl/log", + ], + deps = [ + "//src/core:time", + ], +) + grpc_cc_library( name = "event_engine_extensions", hdrs = [ @@ -137,6 +159,7 @@ grpc_cc_library( "absl/utility", ], deps = [ + "context_list_entry", "resolved_address", "slice", "slice_buffer", @@ -530,8 +553,8 @@ grpc_cc_library( "util/status_helper.h", ], external_deps = [ - "@com_google_protobuf//upb:base", - "@com_google_protobuf//upb:mem", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", "absl/log:check", "absl/status", "absl/strings", @@ -556,6 +579,7 @@ grpc_cc_library( name = "unique_type_name", hdrs = ["util/unique_type_name.h"], external_deps = ["absl/strings"], + visibility = ["//bazel:core_credentials"], deps = [ "useful", "//:gpr_platform", @@ -724,21 +748,25 @@ grpc_cc_library( "absl/log", "absl/log:check", "absl/random", + "absl/functional:any_invocable", "absl/strings", "absl/strings:str_format", ], deps = [ "activity", "arena", + "channelz_property_list", "check_class_size", "construct_destruct", "context", "event_engine_context", + "json_writer", "latent_see", "poll", "promise_factory", "ref_counted", "sync", + "//:channelz", "//:event_engine_base_hdrs", "//:exec_ctx", "//:gpr", @@ -756,6 +784,7 @@ grpc_cc_library( public_hdrs = [ "lib/promise/context.h", ], + visibility = ["//bazel:core_credentials"], deps = [ "down_cast", "//:gpr", @@ -770,6 +799,7 @@ grpc_cc_library( "absl/strings", ], public_hdrs = ["lib/promise/map.h"], + visibility = ["//bazel:core_credentials"], deps = [ "poll", "promise_like", @@ -834,6 +864,7 @@ grpc_cc_library( public_hdrs = [ "lib/promise/arena_promise.h", ], + visibility = ["//bazel:core_credentials"], deps = [ "arena", "construct_destruct", @@ -848,13 +879,19 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/meta:type_traits", + "absl/strings", + "@com_google_protobuf//upb/reflection", ], public_hdrs = [ "lib/promise/detail/promise_like.h", ], deps = [ + "channelz_property_list", "poll", + "upb_utils", "//:gpr_platform", + "//:promise_upb", + "//:promise_upbdefs", "//src/core:function_signature", "//src/core:json", ], @@ -926,7 +963,11 @@ grpc_cc_library( grpc_cc_library( name = "race", public_hdrs = ["lib/promise/race.h"], - deps = ["//:gpr_platform"], + deps = [ + "json", + "//:gpr_platform", + "//:promise_upb", + ], ) grpc_cc_library( @@ -948,9 +989,11 @@ grpc_cc_library( "lib/promise/loop.h", ], deps = [ + "activity", "construct_destruct", "poll", "promise_factory", + "seq", "//:gpr_platform", "//:grpc_trace", ], @@ -1071,6 +1114,7 @@ grpc_cc_library( public_hdrs = [ "lib/promise/seq.h", ], + visibility = ["//bazel:core_credentials"], deps = [ "basic_seq", "poll", @@ -1118,6 +1162,7 @@ grpc_cc_library( public_hdrs = [ "lib/promise/activity.h", ], + visibility = ["//bazel:core_credentials"], deps = [ "atomic_utils", "construct_destruct", @@ -1141,6 +1186,7 @@ grpc_cc_library( "lib/promise/exec_ctx_wakeup_scheduler.h", ], external_deps = ["absl/status"], + visibility = ["//bazel:core_credentials"], deps = [ "closure", "error", @@ -1317,6 +1363,9 @@ grpc_cc_library( grpc_cc_library( name = "mpsc", + srcs = [ + "lib/promise/mpsc.cc", + ], hdrs = [ "lib/promise/mpsc.h", ], @@ -1324,6 +1373,30 @@ grpc_cc_library( "absl/base:core_headers", "absl/log:check", ], + deps = [ + "activity", + "channelz_property_list", + "dump_args", + "map", + "poll", + "ref_counted", + "status_flag", + "sync", + "wait_set", + "//:gpr", + "//:ref_counted_ptr", + ], +) + +grpc_cc_library( + name = "lock_based_mpsc", + hdrs = [ + "lib/promise/lock_based_mpsc.h", + ], + external_deps = [ + "absl/base:core_headers", + "absl/log:check", + ], deps = [ "activity", "dump_args", @@ -1383,6 +1456,7 @@ grpc_cc_library( "absl/log:check", ], public_hdrs = ["util/ref_counted.h"], + visibility = ["//bazel:ref_counted_ptr"], deps = [ "atomic_utils", "down_cast", @@ -1546,6 +1620,22 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "call_creds_registry", + hdrs = [ + "credentials/call/call_creds_registry.h", + ], + external_deps = ["absl/strings"], + deps = [ + "json", + "json_args", + "ref_counted", + "validation_errors", + "//:gpr_platform", + "//:ref_counted_ptr", + ], +) + grpc_cc_library( name = "event_engine_memory_allocator", hdrs = [ @@ -1924,22 +2014,6 @@ grpc_cc_library( deps = ["//:gpr"], ) -grpc_cc_library( - name = "forkable", - srcs = [ - "lib/event_engine/forkable.cc", - ], - hdrs = [ - "lib/event_engine/forkable.h", - ], - external_deps = ["absl/log:check"], - deps = [ - "//:config_vars", - "//:gpr_platform", - "//:grpc_trace", - ], -) - grpc_cc_library( name = "event_engine_poller", hdrs = [ @@ -1969,6 +2043,7 @@ grpc_cc_library( ], external_deps = ["absl/strings"], deps = [ + "event_engine_common", "//:event_engine_base_hdrs", "//:gpr_platform", ], @@ -2092,7 +2167,6 @@ grpc_cc_library( "event_engine_thread_local", "event_engine_work_queue", "examine_stack", - "forkable", "no_destruct", "notification", "sync", @@ -2132,7 +2206,6 @@ grpc_cc_library( ], deps = [ "event_engine_thread_pool", - "forkable", "notification", "posix_event_engine_timer", "sync", @@ -2143,6 +2216,71 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "posix_event_engine_posix_interface", + srcs = [ + "lib/event_engine/posix_engine/posix_interface_posix.cc", + "lib/event_engine/posix_engine/posix_interface_windows.cc", + ], + hdrs = [ + "lib/event_engine/posix_engine/posix_interface.h", + ], + external_deps = [ + "absl/cleanup", + "absl/functional:any_invocable", + "absl/log:check", + "absl/log:log", + "absl/status", + "absl/strings", + "absl/strings:str_format", + ], + deps = [ + "event_engine_tcp_socket_utils", + "experiments", + "iomgr_port", + "posix_event_engine_file_descriptor_collection", + "posix_event_engine_tcp_socket_utils", + "status_helper", + "strerror", + "sync", + "//:event_engine_base_hdrs", + "//:gpr", + "//:gpr_platform", + ], +) + +grpc_cc_library( + name = "posix_event_engine_file_descriptor_collection", + srcs = [ + "lib/event_engine/posix_engine/file_descriptor_collection.cc", + ], + hdrs = [ + "lib/event_engine/posix_engine/file_descriptor_collection.h", + ], + external_deps = [ + "absl/cleanup", + "absl/container:flat_hash_set", + "absl/functional:any_invocable", + "absl/log:check", + "absl/log:log", + "absl/status", + "absl/strings", + "absl/strings:str_format", + ], + deps = [ + "event_engine_tcp_socket_utils", + "experiments", + "iomgr_port", + "posix_event_engine_tcp_socket_utils", + "status_helper", + "strerror", + "sync", + "//:event_engine_base_hdrs", + "//:gpr", + "//:gpr_platform", + ], +) + grpc_cc_library( name = "posix_event_engine_event_poller", srcs = [], @@ -2156,8 +2294,8 @@ grpc_cc_library( ], deps = [ "event_engine_poller", - "forkable", "posix_event_engine_closure", + "posix_event_engine_posix_interface", "//:event_engine_base_hdrs", "//:gpr_platform", ], @@ -2206,7 +2344,10 @@ grpc_cc_library( "lib/event_engine/posix_engine/wakeup_fd_posix.h", ], external_deps = ["absl/status"], - deps = ["//:gpr_platform"], + deps = [ + "posix_event_engine_posix_interface", + "//:gpr_platform", + ], ) grpc_cc_library( @@ -2224,6 +2365,7 @@ grpc_cc_library( ], deps = [ "iomgr_port", + "posix_event_engine_posix_interface", "posix_event_engine_wakeup_fd_posix", "strerror", "//:gpr", @@ -2245,6 +2387,7 @@ grpc_cc_library( ], deps = [ "iomgr_port", + "posix_event_engine_posix_interface", "posix_event_engine_wakeup_fd_posix", "strerror", "//:gpr", @@ -2265,6 +2408,7 @@ grpc_cc_library( ], deps = [ "iomgr_port", + "posix_event_engine_posix_interface", "posix_event_engine_wakeup_fd_posix", "posix_event_engine_wakeup_fd_posix_eventfd", "posix_event_engine_wakeup_fd_posix_pipe", @@ -2282,6 +2426,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/container:flat_hash_set", "absl/container:inlined_vector", "absl/functional:function_ref", "absl/log", @@ -2299,6 +2444,7 @@ grpc_cc_library( "posix_event_engine_event_poller", "posix_event_engine_internal_errqueue", "posix_event_engine_lockfree_event", + "posix_event_engine_posix_interface", "posix_event_engine_wakeup_fd_posix", "posix_event_engine_wakeup_fd_posix_default", "status_helper", @@ -2336,6 +2482,7 @@ grpc_cc_library( "iomgr_port", "posix_event_engine_closure", "posix_event_engine_event_poller", + "posix_event_engine_posix_interface", "posix_event_engine_wakeup_fd_posix", "posix_event_engine_wakeup_fd_posix_default", "status_helper", @@ -2358,7 +2505,6 @@ grpc_cc_library( ], external_deps = ["absl/strings"], deps = [ - "forkable", "iomgr_port", "no_destruct", "posix_event_engine_event_poller", @@ -2380,6 +2526,7 @@ grpc_cc_library( external_deps = ["absl/log"], deps = [ "iomgr_port", + "posix_event_engine_posix_interface", "strerror", "//:gpr", ], @@ -2401,11 +2548,33 @@ grpc_cc_library( deps = [ "iomgr_port", "posix_event_engine_internal_errqueue", + "posix_event_engine_posix_interface", + "posix_write_event_sink", "sync", + "//:event_engine_base_hdrs", "//:gpr", ], ) +grpc_cc_library( + name = "posix_write_event_sink", + srcs = [ + "lib/event_engine/posix_engine/posix_write_event_sink.cc", + ], + hdrs = [ + "lib/event_engine/posix_engine/posix_write_event_sink.h", + ], + external_deps = [ + "absl/base:no_destructor", + "absl/functional:any_invocable", + ], + deps = [ + "bitset", + "event_engine_common", + "//:event_engine_base_hdrs", + ], +) + grpc_cc_library( name = "posix_event_engine_endpoint", srcs = [ @@ -2437,6 +2606,7 @@ grpc_cc_library( "posix_event_engine_closure", "posix_event_engine_event_poller", "posix_event_engine_internal_errqueue", + "posix_event_engine_posix_interface", "posix_event_engine_tcp_socket_utils", "posix_event_engine_traced_buffer_list", "ref_counted", @@ -2528,6 +2698,7 @@ grpc_cc_library( deps = [ "event_engine_tcp_socket_utils", "iomgr_port", + "posix_event_engine_posix_interface", "posix_event_engine_tcp_socket_utils", "socket_mutator", "status_helper", @@ -2561,6 +2732,7 @@ grpc_cc_library( "posix_event_engine_endpoint", "posix_event_engine_event_poller", "posix_event_engine_listener_utils", + "posix_event_engine_posix_interface", "posix_event_engine_tcp_socket_utils", "socket_mutator", "status_helper", @@ -2580,8 +2752,10 @@ grpc_cc_library( hdrs = ["lib/event_engine/posix_engine/posix_engine.h"], external_deps = [ "absl/base:core_headers", + "absl/base:no_destructor", "absl/cleanup", "absl/container:flat_hash_map", + "absl/container:inlined_vector", "absl/functional:any_invocable", "absl/hash", "absl/log", @@ -2598,8 +2772,6 @@ grpc_cc_library( "event_engine_thread_pool", "event_engine_utils", "experiments", - "forkable", - "init_internally", "iomgr_port", "native_posix_dns_resolver", "no_destruct", @@ -2609,6 +2781,7 @@ grpc_cc_library( "posix_event_engine_event_poller", "posix_event_engine_listener", "posix_event_engine_poller_posix_default", + "posix_event_engine_posix_interface", "posix_event_engine_tcp_socket_utils", "posix_event_engine_timer", "posix_event_engine_timer_manager", @@ -2645,7 +2818,6 @@ grpc_cc_library( "event_engine_tcp_socket_utils", "event_engine_thread_pool", "event_engine_utils", - "init_internally", "iomgr_port", "posix_event_engine_timer_manager", "sync", @@ -2782,6 +2954,11 @@ grpc_cc_library( "lib/event_engine/cf_engine/cftype_unique_ref.h", "lib/event_engine/cf_engine/dns_service_resolver.h", ], + defines = select({ + ":maximize_threadyness": ["GRPC_CFSTREAM_MAX_THREADPOOL_SIZE=16u"], + ":minimize_threadyness": ["GRPC_CFSTREAM_MAX_THREADPOOL_SIZE=2u"], + "//conditions:default": [], + }), external_deps = [ "absl/container:flat_hash_map", "absl/log", @@ -2795,7 +2972,6 @@ grpc_cc_library( "event_engine_tcp_socket_utils", "event_engine_thread_pool", "event_engine_utils", - "init_internally", "posix_event_engine_closure", "posix_event_engine_event_poller", "posix_event_engine_lockfree_event", @@ -2803,6 +2979,7 @@ grpc_cc_library( "ref_counted", "strerror", "sync", + "useful", "//:event_engine_base_hdrs", "//:gpr", "//:parse_address", @@ -2963,6 +3140,17 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "endpoint_channel_arg_wrapper", + srcs = ["lib/event_engine/endpoint_channel_arg_wrapper.cc"], + hdrs = ["lib/event_engine/endpoint_channel_arg_wrapper.h"], + deps = [ + "ref_counted", + "useful", + "//:grpc_public_hdrs", + ], +) + grpc_cc_library( name = "ref_counted_dns_resolver_interface", hdrs = ["lib/event_engine/ref_counted_dns_resolver_interface.h"], @@ -3032,6 +3220,8 @@ grpc_cc_library( "iomgr_port", "posix_event_engine_closure", "posix_event_engine_event_poller", + "posix_event_engine_file_descriptor_collection", + "posix_event_engine_posix_interface", "posix_event_engine_tcp_socket_utils", "ref_counted_dns_resolver_interface", "resolved_address", @@ -3124,6 +3314,7 @@ grpc_cc_library( hdrs = [ "lib/iomgr/pollset_set.h", ], + visibility = ["//bazel:alt_grpc_base_legacy"], deps = [ "iomgr_fwd", "//:gpr", @@ -3351,6 +3542,7 @@ grpc_cc_library( deps = [ "avl", "channel_stack_type", + "channelz_property_list", "dual_ref_counted", "ref_counted", "ref_counted_string", @@ -3485,6 +3677,7 @@ grpc_cc_library( ], deps = [ "arena", + "blackboard", "channel_fwd", "client_channel_internal_header", "grpc_service_config", @@ -3599,6 +3792,7 @@ grpc_cc_library( ], external_deps = ["absl/base:core_headers"], deps = [ + "blackboard", "ref_counted", "sync", "useful", @@ -3811,9 +4005,9 @@ grpc_cc_library( "load_balancing/backend_metric_parser.h", ], external_deps = [ - "@com_google_protobuf//upb:base", - "@com_google_protobuf//upb:mem", - "@com_google_protobuf//upb:message", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", + "@com_google_protobuf//upb/message", "absl/strings", ], deps = [ @@ -4311,6 +4505,7 @@ grpc_cc_library( "closure", "error", "iomgr_fwd", + "ssl_transport_security_utils", "sync", "unique_type_name", "useful", @@ -4446,6 +4641,8 @@ grpc_cc_library( "ref_counted", "slice", "slice_refcount", + "ssl_key_logging", + "ssl_transport_security_utils", "status_helper", "sync", "unique_type_name", @@ -4539,6 +4736,25 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "jwt_util", + srcs = ["credentials/call/jwt_util.cc"], + hdrs = ["credentials/call/jwt_util.h"], + external_deps = [ + "absl/status", + "absl/status:statusor", + "absl/strings", + ], + deps = [ + "json", + "json_args", + "json_object_loader", + "json_reader", + "time", + "//:gpr", + ], +) + grpc_cc_library( name = "gcp_service_account_identity_credentials", srcs = [ @@ -4556,10 +4772,7 @@ grpc_cc_library( deps = [ "closure", "error", - "json", - "json_args", - "json_object_loader", - "json_reader", + "jwt_util", "metadata", "slice", "status_conversion", @@ -4580,6 +4793,35 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "jwt_token_file_call_credentials", + srcs = [ + "credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc", + ], + hdrs = [ + "credentials/call/jwt_token_file/jwt_token_file_call_credentials.h", + ], + external_deps = [ + "absl/functional:any_invocable", + "absl/status", + "absl/status:statusor", + "absl/strings", + ], + deps = [ + "jwt_util", + "load_file", + "time", + "token_fetcher_credentials", + "unique_type_name", + "//:gpr", + "//:grpc_base", + "//:grpc_core_credentials_header", + "//:grpc_security_base", + "//:orphanable", + "//:ref_counted_ptr", + ], +) + grpc_cc_library( name = "grpc_oauth2_credentials", srcs = [ @@ -4709,6 +4951,8 @@ grpc_cc_library( "closure", "error", "iomgr_fwd", + "ssl_key_logging", + "ssl_transport_security_utils", "unique_type_name", "//:channel_arg_names", "//:debug_location", @@ -5214,8 +5458,8 @@ grpc_cc_library( "load_balancing/grpclb/load_balancer_api.h", ], external_deps = [ - "@com_google_protobuf//upb:base", - "@com_google_protobuf//upb:mem", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", "absl/base:core_headers", "absl/container:inlined_vector", "absl/functional:function_ref", @@ -5332,8 +5576,8 @@ grpc_cc_library( "load_balancing/rls/rls.h", ], external_deps = [ - "@com_google_protobuf//upb:base", - "@com_google_protobuf//upb:mem", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", "absl/base:core_headers", "absl/hash", "absl/log", @@ -5415,9 +5659,15 @@ grpc_cc_library( "util/upb_utils.h", ], external_deps = [ - "@com_google_protobuf//upb:base", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", "absl/strings", ], + deps = [ + "//:gpr", + "//:protobuf_duration_upb", + "//:protobuf_timestamp_upb", + ], ) grpc_cc_library( @@ -5448,6 +5698,7 @@ grpc_cc_library( "error", "grpc_matchers", "grpc_tls_credentials", + "ssl_transport_security_utils", "sync", "unique_type_name", "useful", @@ -5583,10 +5834,11 @@ grpc_cc_library( external_deps = [ "absl/status:statusor", "absl/strings", - "@com_google_protobuf//upb:reflection", + "@com_google_protobuf//upb/reflection", ], tags = ["nofixdeps"], deps = [ + "blackboard", "channel_args", "channel_fwd", "interception_chain", @@ -5674,6 +5926,7 @@ grpc_cc_library( tags = ["nofixdeps"], visibility = ["//bazel:xds_client_core"], deps = [ + "call_creds_registry", "channel_creds_registry", "//:ref_counted_ptr", "//:xds_client", @@ -5693,8 +5946,10 @@ grpc_cc_library( ], tags = ["nofixdeps"], deps = [ + "call_creds_registry", "channel_creds_registry", "down_cast", + "env", "json", "json_args", "json_object_loader", @@ -5859,15 +6114,16 @@ grpc_cc_library( "absl/strings:str_format", "absl/synchronization", "absl/types:span", - "@com_google_protobuf//upb:base", - "@com_google_protobuf//upb:mem", - "@com_google_protobuf//upb:text", - "@com_google_protobuf//upb:json", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", + "@com_google_protobuf//upb/text", + "@com_google_protobuf//upb/json", "re2", - "@com_google_protobuf//upb:reflection", - "@com_google_protobuf//upb:message", + "@com_google_protobuf//upb/reflection", + "@com_google_protobuf//upb/message", ], tags = ["nofixdeps"], + visibility = ["//bazel:xds_client_grpc"], deps = [ "certificate_provider_factory", "certificate_provider_registry", @@ -5972,6 +6228,7 @@ grpc_cc_library( "rls_config_upbdefs", "slice", "slice_refcount", + "ssl_transport_security_utils", "status_conversion", "status_helper", "sync", @@ -5995,6 +6252,7 @@ grpc_cc_library( "xds_route_config", "xds_server_grpc", "xds_transport_grpc", + "xds_type_matcher_upb", "xds_type_upb", "xds_type_upbdefs", "//:channel", @@ -6044,6 +6302,7 @@ grpc_cc_library( tags = ["nofixdeps"], visibility = ["//bazel:xds_client_core"], deps = [ + "call_creds_registry", "channel_args", "channel_creds_registry", "channel_fwd", @@ -6124,6 +6383,7 @@ grpc_cc_library( "channel_args", "channel_args_preconditioning", "channel_fwd", + "down_cast", "grpc_server_config_selector", "grpc_server_config_selector_filter", "grpc_service_config", @@ -6192,6 +6452,30 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "call_creds_registry_init", + srcs = [ + "credentials/call/call_creds_registry_init.cc", + ], + external_deps = ["absl/strings"], + deps = [ + "call_creds_registry", + "down_cast", + "json", + "json_args", + "json_object_loader", + "jwt_token_file_call_credentials", + "time", + "validation_errors", + "//:config", + "//:gpr", + "//:gpr_platform", + "//:grpc_core_credentials_header", + "//:grpc_security_base", + "//:ref_counted_ptr", + ], +) + grpc_cc_library( name = "grpc_lb_policy_cds", srcs = [ @@ -6250,12 +6534,28 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "shared_bit_gen", - srcs = ["util/shared_bit_gen.cc"], - hdrs = [ - "util/shared_bit_gen.h", +config_setting( + name = "grpc_cpu_intensive_bitgen_setting", + values = {"define": "grpc_bitgen_implementation=cpu_intensive"}, +) + +config_setting( + name = "grpc_mem_intensive_bitgen_setting", + values = {"define": "grpc_bitgen_implementation=mem_intensive"}, +) + +grpc_cc_library( + name = "shared_bit_gen", + srcs = ["util/shared_bit_gen.cc"], + hdrs = [ + "util/shared_bit_gen.h", ], + # Select the appropriate SharedBitGen implementation based on the build flag. + defines = select({ + ":grpc_cpu_intensive_bitgen_setting": ["GRPC_CPU_INTENSIVE_BITGEN"], + ":grpc_mem_intensive_bitgen_setting": ["GRPC_MEM_INTENSIVE_BITGEN"], + "//conditions:default": [], + }), external_deps = [ "absl/random", ], @@ -6425,8 +6725,8 @@ grpc_cc_library( "load_balancing/health_check_client_internal.h", ], external_deps = [ - "@com_google_protobuf//upb:base", - "@com_google_protobuf//upb:mem", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", "absl/base:core_headers", "absl/log", "absl/log:check", @@ -7064,8 +7364,8 @@ grpc_cc_library( "ext/filters/backend_metrics/backend_metric_filter.h", ], external_deps = [ - "@com_google_protobuf//upb:base", - "@com_google_protobuf//upb:mem", + "@com_google_protobuf//upb/base", + "@com_google_protobuf//upb/mem", "absl/log", "absl/status:statusor", "absl/strings", @@ -7294,11 +7594,13 @@ grpc_cc_library( grpc_cc_library( name = "context_list_entry", + srcs = [ + "telemetry/context_list_entry.cc", + ], hdrs = [ "telemetry/context_list_entry.h", ], deps = [ - "tcp_tracer", "//:gpr", ], ) @@ -7419,6 +7721,7 @@ grpc_cc_library( deps = [ "arena", "arena_promise", + "blackboard", "channel_args", "channel_fwd", "client_channel_internal_header", @@ -7536,6 +7839,7 @@ grpc_cc_library( ], deps = [ "bdp_estimator", + "channelz_property_list", "experiments", "http2_settings", "memory_quota", @@ -7581,6 +7885,7 @@ grpc_cc_library( "absl/random:distributions", ], deps = [ + "channelz_property_list", "time", "//:event_engine_base_hdrs", "//:gpr_platform", @@ -7614,10 +7919,12 @@ grpc_cc_library( external_deps = ["absl/strings"], deps = [ "channel_args", + "channelz_property_list", "experiments", "match", "time", "//:channel_arg_names", + "//:gpr", "//:gpr_platform", ], ) @@ -7658,8 +7965,8 @@ grpc_cc_library( "absl/strings", ], deps = [ + "channelz_property_list", "http2_status", - "json", "useful", "//:chttp2_frame", "//:gpr_platform", @@ -7702,10 +8009,12 @@ grpc_cc_library( deps = [ "http2_status", "metadata_batch", + "shared_bit_gen", ":slice", ":slice_buffer", "//:chttp2_frame", "//:gpr_platform", + "//:hpack_encoder", "//:hpack_parser", "//:ref_counted_ptr", ], @@ -7782,6 +8091,7 @@ grpc_cc_library( "call_spine", "channel_args", "check_class_size", + "connectivity_state", "for_each", "grpc_promise_endpoint", "header_assembler", @@ -7790,15 +8100,18 @@ grpc_cc_library( "http2_transport", "inter_activity_mutex", "internal_channel_arg_names", + "keepalive", "latent_see", "loop", "map", "message", "message_assembler", "metadata", + "metadata_batch", "mpsc", "ping_promise", "sync", + "transport_common", ":match_promise", ":poll", ":slice", @@ -7810,6 +8123,7 @@ grpc_cc_library( "//:grpc_trace", "//:hpack_encoder", "//:hpack_parser", + "//:orphanable", "//:promise", "//:ref_counted_ptr", ], @@ -7863,6 +8177,35 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "http2_stats_collector", + srcs = [ + "ext/transport/chttp2/transport/http2_stats_collector.cc", + ], + hdrs = [ + "ext/transport/chttp2/transport/http2_stats_collector.h", + ], + deps = [ + "stats_data", + "//:grpc_core_credentials_header", + "//:grpc_public_hdrs", + ], +) + +grpc_cc_library( + name = "transport_common", + srcs = [ + "ext/transport/chttp2/transport/transport_common.cc", + ], + hdrs = [ + "ext/transport/chttp2/transport/transport_common.h", + ], + external_deps = [ + ], + deps = [ + ], +) + grpc_cc_library( name = "http2_transport", srcs = [ @@ -7954,11 +8297,13 @@ grpc_cc_library( "channel_args_preconditioning", "channel_stack_type", "closure", + "endpoint_channel_arg_wrapper", "endpoint_transport_client_channel_factory", "error", "error_utils", "grpc_insecure_credentials", "handshaker_registry", + "http2_client_transport", "resolved_address", "status_helper", "subchannel_connector", @@ -8017,6 +8362,7 @@ grpc_cc_library( "event_engine_common", "event_engine_extensions", "event_engine_query_extensions", + "event_engine_shim", "event_engine_tcp_socket_utils", "event_engine_utils", "grpc_insecure_credentials", @@ -8216,6 +8562,7 @@ grpc_cc_library( ], external_deps = [ "absl/strings", + "absl/log", ], deps = [ "chaotic_good_frame_header", @@ -8316,11 +8663,17 @@ grpc_cc_library( ], external_deps = [ "absl/cleanup", + "absl/container:inlined_vector", "absl/strings", + "absl/time", + "absl/log", ], deps = [ "1999", + "channelz_property_list", + "chaotic_good_frame_transport", "chaotic_good_pending_connection", + "chaotic_good_scheduler", "chaotic_good_serialize_little_endian", "chaotic_good_tcp_frame_header", "chaotic_good_tcp_ztrace_collector", @@ -8332,17 +8685,23 @@ grpc_cc_library( "event_engine_query_extensions", "event_engine_tcp_socket_utils", "grpc_promise_endpoint", + "latent_see", "loop", "map", "metrics", + "mpsc", + "race", + "ref_counted", "seq", "seq_bit_set", + "shared_bit_gen", "slice_buffer", "status_flag", "time", "transport_framing_endpoint_extension", "try_seq", "//:channelz", + "//:event_engine_base_hdrs", "//:gpr", "//:promise", ], @@ -8380,6 +8739,24 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "chaotic_good_scheduler", + srcs = [ + "ext/transport/chaotic_good/scheduler.cc", + ], + hdrs = [ + "ext/transport/chaotic_good/scheduler.h", + ], + external_deps = [ + "absl/log", + "absl/strings", + ], + deps = [ + "chaotic_good_tcp_ztrace_collector", + "shared_bit_gen", + ], +) + grpc_cc_library( name = "chaotic_good_tcp_frame_transport", srcs = [ @@ -8505,6 +8882,7 @@ grpc_cc_library( "1999", "activity", "arena", + "channelz_property_list", "chaotic_good_config", "chaotic_good_frame", "chaotic_good_frame_header", @@ -8580,6 +8958,7 @@ grpc_cc_library( "event_engine_context", "event_engine_extensions", "event_engine_query_extensions", + "event_engine_shim", "event_engine_tcp_socket_utils", "event_engine_utils", "event_engine_wakeup_scheduler", @@ -8593,6 +8972,7 @@ grpc_cc_library( "metadata", "metadata_batch", "metrics", + "posix_event_engine_base_hdrs", "race", "resource_quota", "shared_bit_gen", @@ -8858,9 +9238,9 @@ grpc_cc_library( "event_engine_context", "event_engine_tcp_socket_utils", "grpc_promise_endpoint", + "lock_based_mpsc", "loop", "match_promise", - "mpsc", "seq", "try_join", "try_seq", @@ -8903,12 +9283,12 @@ grpc_cc_library( "grpc_promise_endpoint", "if", "inter_activity_pipe", + "lock_based_mpsc", "loop", "map", "memory_quota", "metadata_batch", "metrics", - "mpsc", "pipe", "poll", "resource_quota", @@ -8964,11 +9344,11 @@ grpc_cc_library( "if", "inter_activity_latch", "inter_activity_pipe", + "lock_based_mpsc", "loop", "memory_quota", "metadata_batch", "metrics", - "mpsc", "pipe", "poll", "resource_quota", @@ -9021,6 +9401,7 @@ grpc_cc_library( "event_engine_context", "event_engine_extensions", "event_engine_query_extensions", + "event_engine_shim", "event_engine_tcp_socket_utils", "event_engine_utils", "event_engine_wakeup_scheduler", @@ -9436,6 +9817,7 @@ grpc_cc_library( hdrs = [ "call/metadata.h", ], + visibility = ["//bazel:core_credentials"], deps = [ "error_utils", "metadata_batch", @@ -9675,9 +10057,14 @@ grpc_cc_library( grpc_cc_library( name = "wait_for_single_owner", + srcs = ["util/wait_for_single_owner.cc"], hdrs = ["util/wait_for_single_owner.h"], - external_deps = ["absl/log"], + external_deps = [ + "absl/log", + "absl/functional:any_invocable", + ], deps = [ + "no_destruct", "time", "//:gpr", ], @@ -9764,8 +10151,8 @@ grpc_cc_library( "json_object_loader", "json_reader", "load_file", + "ssl_transport_security_utils", "status_helper", - "//:tsi_ssl_credentials", ], ) @@ -9781,6 +10168,7 @@ grpc_cc_library( ], deps = [ "json_writer", + "memory_usage", "single_set_ptr", "sync", "time", @@ -9802,6 +10190,256 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "channelz_property_list", + srcs = ["channelz/property_list.cc"], + hdrs = ["channelz/property_list.h"], + external_deps = [ + "absl/strings", + "absl/status", + "absl/container:flat_hash_map", + "@com_google_protobuf//upb/mem", + "@com_google_protobuf//upb/text", + ], + deps = [ + "json", + "match", + "time", + "upb_utils", + "//:channelz_property_list_upb", + "//:channelz_upb", + "//:gpr", + "//:protobuf_any_upb", + "//:protobuf_empty_upb", + ], +) + +grpc_cc_library( + name = "ssl_transport_security_utils", + srcs = [ + "//src/core:tsi/ssl_transport_security_utils.cc", + ], + hdrs = [ + "//src/core:tsi/ssl_transport_security_utils.h", + ], + external_deps = [ + "absl/base:core_headers", + "absl/log:check", + "absl/log:log", + "absl/status", + "absl/status:statusor", + "absl/strings", + "libcrypto", + "libssl", + ], + deps = [ + "channel_args", + "env", + "error", + "grpc_transport_chttp2_alpn", + "load_file", + "ref_counted", + "slice", + "ssl_key_logging", + "sync", + "tsi_ssl_types", + "useful", + "//:channel_arg_names", + "//:config_vars", + "//:gpr", + "//:grpc_base", + "//:grpc_core_credentials_header", + "//:grpc_credentials_util", + "//:grpc_public_hdrs", + "//:grpc_security_base", + "//:ref_counted_ptr", + "//:transport_auth_context", + "//:tsi_base", + "//:tsi_ssl_session_cache", + ], +) + +grpc_cc_library( + name = "ssl_key_logging", + srcs = [ + "//src/core:tsi/ssl/key_logging/ssl_key_logging.cc", + ], + hdrs = [ + "//src/core:tsi/ssl/key_logging/ssl_key_logging.h", + ], + external_deps = [ + "absl/base:core_headers", + "absl/log:check", + "absl/log:log", + "absl/status", + "absl/status:statusor", + "absl/strings", + "libcrypto", + "libssl", + ], + visibility = ["//visibility:public"], + deps = [ + "channel_args", + "env", + "error", + "grpc_transport_chttp2_alpn", + "load_file", + "ref_counted", + "slice", + "sync", + "tsi_ssl_types", + "useful", + "//:channel_arg_names", + "//:config_vars", + "//:gpr", + "//:grpc_base", + "//:grpc_core_credentials_header", + "//:grpc_credentials_util", + "//:grpc_public_hdrs", + "//:grpc_security_base", + "//:ref_counted_ptr", + "//:transport_auth_context", + "//:tsi_base", + "//:tsi_ssl_session_cache", + ], +) + +grpc_cc_library( + name = "zviz_strings", + srcs = [ + "channelz/zviz/strings.cc", + ], + hdrs = ["channelz/zviz/strings.h"], + external_deps = [ + "absl/strings", + ], +) + +grpc_cc_library( + name = "zviz_environment", + srcs = [ + "channelz/zviz/environment.cc", + ], + hdrs = ["channelz/zviz/environment.h"], + external_deps = [ + "absl/strings", + "absl/status:statusor", + ], + deps = [ + "zviz_strings", + "//src/proto/grpc/channelz/v2:channelz_cc_proto", + ], +) + +grpc_cc_library( + name = "zviz_layout", + srcs = [ + "channelz/zviz/layout.cc", + ], + hdrs = ["channelz/zviz/layout.h"], + deps = [ + "zviz_environment", + "//src/proto/grpc/channelz/v2:channelz_cc_proto", + "@com_google_protobuf//:duration_cc_proto", + "@com_google_protobuf//:timestamp_cc_proto", + ], +) + +grpc_cc_library( + name = "zviz_data", + srcs = [ + "channelz/zviz/data.cc", + ], + hdrs = ["channelz/zviz/data.h"], + external_deps = [ + "absl/container:flat_hash_map", + "absl/strings", + "absl/types:span", + ], + deps = [ + "no_destruct", + "zviz_environment", + "zviz_layout", + "//src/proto/grpc/channelz/v2:channelz_cc_proto", + "//src/proto/grpc/channelz/v2:property_list_cc_proto", + ], +) + +grpc_cc_library( + name = "zviz_trace", + srcs = [ + "channelz/zviz/trace.cc", + ], + hdrs = ["channelz/zviz/trace.h"], + external_deps = [ + "absl/container:flat_hash_map", + "absl/strings", + "absl/types:span", + ], + deps = [ + "zviz_data", + "zviz_environment", + "zviz_layout", + "//src/proto/grpc/channelz/v2:channelz_cc_proto", + ], +) + +grpc_cc_library( + name = "zviz_entity", + srcs = [ + "channelz/zviz/entity.cc", + ], + hdrs = ["channelz/zviz/entity.h"], + external_deps = [ + "absl/container:flat_hash_map", + "absl/strings", + "absl/types:span", + ], + deps = [ + "zviz_data", + "zviz_environment", + "zviz_layout", + "zviz_strings", + "zviz_trace", + "//src/proto/grpc/channelz/v2:channelz_cc_proto", + ], +) + +grpc_cc_library( + name = "zviz_html", + srcs = [ + "channelz/zviz/html.cc", + ], + hdrs = ["channelz/zviz/html.h"], + external_deps = [ + "absl/container:flat_hash_map", + "absl/strings", + "absl/strings:string_view", + "absl/types:span", + "absl/functional:function_ref", + ], +) + +grpc_cc_library( + name = "zviz_layout_html", + srcs = [ + "channelz/zviz/layout_html.cc", + ], + hdrs = ["channelz/zviz/layout_html.h"], + external_deps = [ + "absl/container:flat_hash_map", + "absl/strings", + "absl/strings:string_view", + "absl/types:span", + "absl/functional:function_ref", + ], + deps = [ + "zviz_environment", + "zviz_html", + "zviz_layout", + ], +) + ### UPB Targets grpc_upb_proto_library( @@ -10060,6 +10698,11 @@ grpc_upb_proto_reflection_library( deps = ["@com_github_cncf_xds//xds/type/v3:pkg"], ) +grpc_upb_proto_library( + name = "xds_type_matcher_upb", + deps = ["@com_github_cncf_xds//xds/type/matcher/v3:pkg"], +) + grpc_upb_proto_library( name = "xds_orca_upb", deps = ["@com_github_cncf_xds//xds/data/orca/v3:pkg"], diff --git a/deps/grpc/src/core/call/filter_fusion.h b/deps/grpc/src/core/call/filter_fusion.h index ec42894075d..555f4338b7d 100644 --- a/deps/grpc/src/core/call/filter_fusion.h +++ b/deps/grpc/src/core/call/filter_fusion.h @@ -957,26 +957,25 @@ struct FilterWrapper : public FilterWrapper { #undef GRPC_FUSE_METHOD -template -class FusedFilter : public ImplementChannelFilter>, +template +class FusedFilter : public ImplementChannelFilter>, public Filters... { public: static const grpc_channel_filter kFilter; static absl::string_view TypeName() { - static const std::string kName = absl::StrCat( - "Fused_Filter_", - absl::StrJoin(std::make_tuple(Filters::TypeName()...), "_")); + static const std::string kName = + absl::StrCat(absl::StrJoin(std::tuple(Filters::TypeName()...), "+")); return kName; } - static absl::StatusOr>> Create( + static absl::StatusOr>> Create( const ChannelArgs& args, ChannelFilter::Args filter_args) { auto filters_wrapper = std::make_unique>(args, filter_args); GRPC_RETURN_IF_ERROR(filters_wrapper->status()); - return absl::WrapUnique>( - new FusedFilter(std::move(filters_wrapper))); + return absl::WrapUnique>( + new FusedFilter(std::move(filters_wrapper))); } static constexpr bool IsFused = true; @@ -1033,10 +1032,14 @@ class FusedFilter : public ImplementChannelFilter>, std::unique_ptr> filters_; }; +template +const grpc_channel_filter FusedFilter::kFilter = + MakePromiseBasedFilter, ep>(); + } // namespace filters_detail -template -using FusedFilter = filters_detail::FusedFilter; +template +using FusedFilter = filters_detail::FusedFilter; } // namespace grpc_core diff --git a/deps/grpc/src/core/call/interception_chain.h b/deps/grpc/src/core/call/interception_chain.h index 48dda293c4f..bba88f658cd 100644 --- a/deps/grpc/src/core/call/interception_chain.h +++ b/deps/grpc/src/core/call/interception_chain.h @@ -163,11 +163,8 @@ class InterceptionChainBuilder final { RefCountedPtr>; explicit InterceptionChainBuilder(ChannelArgs args, - const Blackboard* old_blackboard = nullptr, - Blackboard* new_blackboard = nullptr) - : args_(std::move(args)), - old_blackboard_(old_blackboard), - new_blackboard_(new_blackboard) {} + const Blackboard* blackboard = nullptr) + : args_(std::move(args)), blackboard_(blackboard) {} // Add a filter with a `Call` class as an inner member. // Call class must be one compatible with the filters described in @@ -176,8 +173,8 @@ class InterceptionChainBuilder final { absl::enable_if_t Add() { if (!status_.ok()) return *this; - auto filter = T::Create(args_, {FilterInstanceId(FilterTypeId()), - old_blackboard_, new_blackboard_}); + auto filter = + T::Create(args_, {FilterInstanceId(FilterTypeId()), blackboard_}); if (!filter.ok()) { status_ = filter.status(); return *this; @@ -193,8 +190,8 @@ class InterceptionChainBuilder final { absl::enable_if_t::value, InterceptionChainBuilder&> Add() { - AddInterceptor(T::Create(args_, {FilterInstanceId(FilterTypeId()), - old_blackboard_, new_blackboard_})); + AddInterceptor( + T::Create(args_, {FilterInstanceId(FilterTypeId()), blackboard_})); return *this; }; @@ -273,8 +270,7 @@ class InterceptionChainBuilder final { absl::Status status_; std::map filter_type_counts_; static std::atomic next_filter_id_; - const Blackboard* old_blackboard_ = nullptr; - Blackboard* new_blackboard_ = nullptr; + const Blackboard* blackboard_ = nullptr; }; } // namespace grpc_core diff --git a/deps/grpc/src/core/channelz/channel_trace.cc b/deps/grpc/src/core/channelz/channel_trace.cc index 3221925cf50..5431b93a24e 100644 --- a/deps/grpc/src/core/channelz/channel_trace.cc +++ b/deps/grpc/src/core/channelz/channel_trace.cc @@ -22,10 +22,12 @@ #include #include +#include #include #include #include "absl/strings/str_cat.h" +#include "google/protobuf/any.upb.h" #include "src/core/channelz/channelz.h" #include "src/core/lib/slice/slice.h" #include "src/core/lib/slice/slice_internal.h" @@ -33,156 +35,252 @@ #include "src/core/util/string.h" #include "src/core/util/sync.h" #include "src/core/util/time.h" +#include "src/core/util/upb_utils.h" +#include "src/proto/grpc/channelz/v2/channelz.upb.h" +#include "upb/base/string_view.h" namespace grpc_core { namespace channelz { -// -// ChannelTrace::TraceEvent -// - -ChannelTrace::TraceEvent::TraceEvent(Severity severity, const grpc_slice& data, - RefCountedPtr referenced_entity) - : timestamp_(Timestamp::Now().as_timespec(GPR_CLOCK_REALTIME)), - severity_(severity), - data_(data), - memory_usage_(sizeof(TraceEvent) + grpc_slice_memory_usage(data)), - referenced_entity_(std::move(referenced_entity)) {} - -ChannelTrace::TraceEvent::TraceEvent(Severity severity, const grpc_slice& data) - : TraceEvent(severity, data, nullptr) {} - -ChannelTrace::TraceEvent::~TraceEvent() { CSliceUnref(data_); } - -RefCountedPtr ChannelTrace::TraceEvent::referenced_entity() const { - return referenced_entity_; -} - // // ChannelTrace // -ChannelTrace::ChannelTrace(size_t max_event_memory) - : max_event_memory_(max_event_memory), - time_created_(Timestamp::Now().as_timespec(GPR_CLOCK_REALTIME)) {} - -ChannelTrace::~ChannelTrace() { - if (max_event_memory_ == 0) { - return; // tracing is disabled if max_event_memory_ == 0 +Json ChannelTrace::RenderJson() const { + if (max_memory_ == 0) return Json(); + Json::Array array; + MutexLock lock(&mu_); + ForEachTraceEventLocked([&array](gpr_timespec timestamp, std::string line) { + Json::Object object = { + {"severity", Json::FromString("CT_INFO")}, + {"timestamp", Json::FromString(gpr_format_timespec(timestamp))}, + {"description", Json::FromString(std::move(line))}, + }; + array.push_back(Json::FromObject(std::move(object))); + }); + Json::Object object; + object["creationTimestamp"] = Json::FromString(creation_timestamp()); + if (num_events_logged_ > 0) { + object["numEventsLogged"] = + Json::FromString(absl::StrCat(num_events_logged_)); } - TraceEvent* it = head_trace_; - while (it != nullptr) { - TraceEvent* to_free = it; - it = it->next(); - delete to_free; + if (!array.empty()) { + object["events"] = Json::FromArray(std::move(array)); } + return Json::FromObject(std::move(object)); } -void ChannelTrace::AddTraceEventHelper(TraceEvent* new_trace_event) { +std::string ChannelTrace::creation_timestamp() const { + return gpr_format_timespec(time_created_.as_timespec(GPR_CLOCK_REALTIME)); +} + +ChannelTrace::EntryRef ChannelTrace::AppendEntry( + EntryRef parent, std::unique_ptr renderer) { + if (max_memory_ == 0) return EntryRef::Sentinel(); MutexLock lock(&mu_); ++num_events_logged_; - // first event case - if (head_trace_ == nullptr) { - head_trace_ = tail_trace_ = new_trace_event; - } else { - // regular event add case - tail_trace_->set_next(new_trace_event); - tail_trace_ = tail_trace_->next(); - } - event_list_memory_usage_ += new_trace_event->memory_usage(); - // maybe garbage collect the tail until we are under the memory limit. - while (event_list_memory_usage_ > max_event_memory_) { - TraceEvent* to_free = head_trace_; - event_list_memory_usage_ -= to_free->memory_usage(); - head_trace_ = head_trace_->next(); - delete to_free; + const auto ref = NewEntry(parent, std::move(renderer)); + while (current_memory_ > max_memory_ && first_entry_ != kSentinelId) { + DropEntryId(first_entry_); + } + if (GPR_UNLIKELY(current_memory_ > max_memory_)) { + entries_.shrink_to_fit(); + current_memory_ = MemoryUsageOf(entries_); } + return ref; } -void ChannelTrace::AddTraceEvent(Severity severity, const grpc_slice& data) { - if (max_event_memory_ == 0) { - CSliceUnref(data); - return; // tracing is disabled if max_event_memory_ == 0 +ChannelTrace::EntryRef ChannelTrace::NewEntry( + EntryRef parent, std::unique_ptr renderer) { + if (parent.id != kSentinelId) { + if (parent.id >= entries_.size()) return EntryRef::Sentinel(); + if (parent.salt != entries_[parent.id].salt) { + // Parent no longer present: no point adding child + return EntryRef::Sentinel(); + } + } + uint16_t id; + if (next_free_entry_ != kSentinelId) { + id = next_free_entry_; + next_free_entry_ = entries_[id].next_chronologically; + } else { + id = entries_.size(); + DCHECK_NE(id, kSentinelId); + entries_.emplace_back(); + current_memory_ = MemoryUsageOf(entries_); + } + Entry& e = entries_[id]; + e.when = Timestamp::Now(); + e.parent = parent.id; + e.first_child = kSentinelId; + e.last_child = kSentinelId; + e.prev_sibling = kSentinelId; + e.next_sibling = kSentinelId; + e.next_chronologically = kSentinelId; + e.renderer = std::move(renderer); + e.prev_chronologically = last_entry_; + if (last_entry_ == kSentinelId) { + DCHECK_EQ(first_entry_, kSentinelId); + first_entry_ = id; + } else { + Entry& last = entries_[last_entry_]; + DCHECK_EQ(last.next_chronologically, kSentinelId); + last.next_chronologically = id; + } + last_entry_ = id; + if (parent.id != kSentinelId) { + Entry& p = entries_[parent.id]; + e.prev_sibling = p.last_child; + if (p.last_child == kSentinelId) { + DCHECK_EQ(p.first_child, kSentinelId); + p.first_child = id; + } else { + Entry& last = entries_[p.last_child]; + DCHECK_EQ(last.next_sibling, kSentinelId); + last.next_sibling = id; + } + p.last_child = id; } - AddTraceEventHelper(new TraceEvent(severity, data)); + current_memory_ += e.renderer->MemoryUsage(); + DCHECK_EQ(MemoryUsageOf(entries_), current_memory_); + return EntryRef{id, e.salt}; } -void ChannelTrace::AddTraceEventWithReference( - Severity severity, const grpc_slice& data, - RefCountedPtr referenced_entity) { - if (max_event_memory_ == 0) { - CSliceUnref(data); - return; // tracing is disabled if max_event_memory_ == 0 +void ChannelTrace::DropEntry(EntryRef entry) { + if (entry.id == kSentinelId) return; + MutexLock lock(&mu_); + if (entry.id >= entries_.size()) return; + Entry& e = entries_[entry.id]; + if (e.salt != entry.salt) return; + DropEntryId(entry.id); +} + +void ChannelTrace::DropEntryId(uint16_t id) { + Entry& e = entries_[id]; + while (e.first_child != kSentinelId) { + DropEntryId(e.first_child); + } + if (e.prev_chronologically != kSentinelId) { + Entry& prev = entries_[e.prev_chronologically]; + DCHECK_EQ(prev.next_chronologically, id); + prev.next_chronologically = e.next_chronologically; + } + if (e.next_chronologically != kSentinelId) { + Entry& next = entries_[e.next_chronologically]; + DCHECK_EQ(next.prev_chronologically, id); + next.prev_chronologically = e.prev_chronologically; + } + if (e.prev_sibling != kSentinelId) { + Entry& prev = entries_[e.prev_sibling]; + DCHECK_EQ(prev.next_sibling, id); + prev.next_sibling = e.next_sibling; + } + if (e.next_sibling != kSentinelId) { + Entry& next = entries_[e.next_sibling]; + DCHECK_EQ(next.prev_sibling, id); + next.prev_sibling = e.prev_sibling; + } + if (e.parent != kSentinelId) { + Entry& p = entries_[e.parent]; + if (p.first_child == id) { + p.first_child = e.next_sibling; + } + if (p.last_child == id) { + p.last_child = e.prev_sibling; + } } - // create and fill up the new event - AddTraceEventHelper( - new TraceEvent(severity, data, std::move(referenced_entity))); + if (first_entry_ == id) { + first_entry_ = e.next_chronologically; + } + if (last_entry_ == id) { + last_entry_ = e.prev_chronologically; + } + ++e.salt; + e.next_chronologically = next_free_entry_; + current_memory_ -= e.renderer->MemoryUsage(); + e.renderer.reset(); + DCHECK_EQ(current_memory_, MemoryUsageOf(entries_)); + next_free_entry_ = id; } -std::string ChannelTrace::TraceEvent::description() const { - char* description = grpc_slice_to_c_string(data_); - std::string s(description); - gpr_free(description); - return s; +void ChannelTrace::ForEachTraceEvent( + absl::FunctionRef callback) const { + MutexLock lock(&mu_); + ForEachTraceEventLocked(callback); } void ChannelTrace::ForEachTraceEventLocked( - absl::FunctionRef)> - callback) const { - TraceEvent* it = head_trace_; - while (it != nullptr) { - callback(it->timestamp(), it->severity(), it->description(), - it->referenced_entity()); - it = it->next(); + absl::FunctionRef callback) const { + uint16_t id = first_entry_; + while (id != kSentinelId) { + const Entry& e = entries_[id]; + if (e.parent == kSentinelId) RenderEntry(e, callback, 0); + id = e.next_chronologically; } } -Json ChannelTrace::RenderJson() const { - // Tracing is disabled if max_event_memory_ == 0. - if (max_event_memory_ == 0) { - return Json(); // JSON null - } - Json::Object object = { - {"creationTimestamp", - Json::FromString(gpr_format_timespec(time_created_))}, - }; - MutexLock lock(&mu_); - if (num_events_logged_ > 0) { - object["numEventsLogged"] = - Json::FromString(absl::StrCat(num_events_logged_)); +void ChannelTrace::RenderEntry( + const Entry& entry, + absl::FunctionRef callback, + int depth) const { + if (entry.renderer != nullptr) { + callback(entry.when.as_timespec(GPR_CLOCK_REALTIME), + entry.renderer->Render()); + } else if (entry.first_child != kSentinelId) { + callback(entry.when.as_timespec(GPR_CLOCK_REALTIME), + "?unknown parent entry?"); } - // Only add in the event list if it is non-empty. - Json::Array array; - ForEachTraceEventLocked([&array](gpr_timespec timestamp, Severity severity, - std::string description, - RefCountedPtr referenced_entity) { - Json::Object object = { - {"description", Json::FromString(description)}, - {"severity", Json::FromString(SeverityString(severity))}, - {"timestamp", Json::FromString(gpr_format_timespec(timestamp))}, - }; - if (referenced_entity != nullptr) { - const bool is_channel = - (referenced_entity->type() == - BaseNode::EntityType::kTopLevelChannel || - referenced_entity->type() == BaseNode::EntityType::kInternalChannel); - object[is_channel ? "channelRef" : "subchannelRef"] = Json::FromObject({ - {(is_channel ? "channelId" : "subchannelId"), - Json::FromString(absl::StrCat(referenced_entity->uuid()))}, - }); + if (entry.first_child != kSentinelId) { + uint16_t id = entry.first_child; + while (id != kSentinelId) { + const Entry& e = entries_[id]; + RenderEntry(e, callback, depth + 1); + id = e.next_sibling; } - array.emplace_back(Json::FromObject(std::move(object))); - }); - if (!array.empty()) { - object["events"] = Json::FromArray(std::move(array)); } - return Json::FromObject(std::move(object)); } -std::string ChannelTrace::creation_timestamp() const { - return gpr_format_timespec(time_created_); +void ChannelTrace::Render(grpc_channelz_v2_Entity* entity, + upb_Arena* arena) const { + MutexLock lock(&mu_); + uint16_t id = first_entry_; + while (id != kSentinelId) { + const Entry& e = entries_[id]; + if (e.parent == kSentinelId) { + RenderEntry(e, grpc_channelz_v2_Entity_add_trace(entity, arena), arena); + } + id = e.next_chronologically; + } +} + +void ChannelTrace::RenderEntry(const Entry& entry, + grpc_channelz_v2_TraceEvent* trace_event, + upb_Arena* arena) const { + TimestampToUpb( + entry.when.as_timespec(GPR_CLOCK_REALTIME), + grpc_channelz_v2_TraceEvent_mutable_timestamp(trace_event, arena)); + if (entry.renderer != nullptr) { + grpc_channelz_v2_TraceEvent_set_description( + trace_event, CopyStdStringToUpbString(entry.renderer->Render(), arena)); + } + for (uint16_t id = entry.first_child; id != kSentinelId; + id = entries_[id].next_sibling) { + auto* child = grpc_channelz_v2_TraceEvent_new(arena); + RenderEntry(entries_[id], child, arena); + size_t length; + auto* bytes = grpc_channelz_v2_TraceEvent_serialize(child, arena, &length); + auto* data = grpc_channelz_v2_Data_new(arena); + grpc_channelz_v2_Data_set_name(data, StdStringToUpbString("child_trace")); + auto* any = grpc_channelz_v2_Data_mutable_value(data, arena); + google_protobuf_Any_set_value( + any, upb_StringView_FromDataAndSize(bytes, length)); + google_protobuf_Any_set_type_url( + any, StdStringToUpbString( + "type.googleapis.com/grpc.channelz.v2.TraceEvent")); + } } +size_t testing::GetSizeofTraceEvent() { return sizeof(ChannelTrace::Entry); } + } // namespace channelz } // namespace grpc_core diff --git a/deps/grpc/src/core/channelz/channel_trace.h b/deps/grpc/src/core/channelz/channel_trace.h index 0d92eedae36..7ae22433cbb 100644 --- a/deps/grpc/src/core/channelz/channel_trace.h +++ b/deps/grpc/src/core/channelz/channel_trace.h @@ -26,10 +26,21 @@ #include #include +#include +#include +#include +#include + #include "absl/base/thread_annotations.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "src/core/lib/debug/trace_flags.h" #include "src/core/util/json/json.h" +#include "src/core/util/memory_usage.h" #include "src/core/util/ref_counted_ptr.h" #include "src/core/util/sync.h" +#include "src/core/util/time.h" +#include "src/proto/grpc/channelz/v2/channelz.upb.h" namespace grpc_core { namespace channelz { @@ -38,71 +49,246 @@ namespace testing { size_t GetSizeofTraceEvent(void); } +namespace detail { + +class Renderer { + public: + virtual ~Renderer() = default; + virtual std::string Render() const = 0; + virtual size_t MemoryUsage() const = 0; +}; + +struct StrCatFn { + template + std::string operator()(const Arg&... args) { + return absl::StrCat(args...); + } +}; + +template +auto AdaptForStorage(A&& a) { + using RawA = std::remove_reference_t; + if constexpr (std::is_same_v, const char*>) { + return absl::string_view(a); + } else { + return RawA(std::forward(a)); + } +} + +template +std::unique_ptr RendererFromConcatenationInner(Args&&... args) { + class R final : public Renderer { + public: + explicit R(Args&&... args) : args_(std::forward(args)...) {} + + std::string Render() const override { + return std::apply(StrCatFn(), args_); + } + size_t MemoryUsage() const override { + return MemoryUsageOf(args_) + sizeof(Renderer); + } + + private: + std::tuple args_; + }; + return std::make_unique(std::forward(args)...); +} + +template +std::unique_ptr RendererFromConcatenation(Args&&... args) { + return RendererFromConcatenationInner( + AdaptForStorage(std::forward(args))...); +} + +struct RendererFromConcatenationFn { + template + auto operator()(Args&&... args) { + return RendererFromConcatenation(std::forward(args)...); + } +}; + +template +void OutputLogFromLogExpr(N* out, std::unique_ptr renderer) { + out->NewNode(std::move(renderer)).Commit(); +} + +template +class LogExpr { + public: + explicit LogExpr(N* node, T&&... values) + : out_(node), values_(std::forward(values)...) {} + + ~LogExpr() { + if (out_ != nullptr) { + OutputLogFromLogExpr(out_, + std::apply(detail::RendererFromConcatenationFn(), + std::move(values_))); + } + } + + template + friend auto operator<<(LogExpr&& x, U&& u) { + auto mk = [out = std::exchange(x.out_, nullptr), + u = AdaptForStorage(std::forward(u))]( + T&&... existing_values) mutable { + return LogExpr( + out, std::forward(existing_values)..., std::move(u)); + }; + return std::apply(mk, std::move(x.values_)); + } + + private: + N* out_; + std::tuple values_; +}; +} // namespace detail + class BaseNode; // Object used to hold live data for a channel. This data is exposed via the // channelz service: // https://github.com/grpc/proposal/blob/master/A14-channelz.md class ChannelTrace { - public: - explicit ChannelTrace(size_t max_event_memory); - ~ChannelTrace(); - - enum Severity { - Unset = 0, // never to be used - Info, // we start at 1 to avoid using proto default values - Warning, - Error + struct EntryRef { + uint16_t id; + uint16_t salt; + static EntryRef Sentinel() { return EntryRef{kSentinelId, 0}; } }; - static const char* SeverityString(ChannelTrace::Severity severity) { - switch (severity) { - case ChannelTrace::Severity::Info: - return "CT_INFO"; - case ChannelTrace::Severity::Warning: - return "CT_WARNING"; - case ChannelTrace::Severity::Error: - return "CT_ERROR"; - default: - GPR_UNREACHABLE_CODE(return "CT_UNKNOWN"); - } - } + public: + explicit ChannelTrace(size_t max_memory) + : max_memory_(std::min(max_memory, sizeof(Entry) * 32768)) {} + + using Renderer = detail::Renderer; - // Adds a new trace event to the tracing object + // Represents a node in the channel trace. + // Nodes form a tree structure, allowing for hierarchical tracing. // - // NOTE: each ChannelTrace tracks the memory used by its list of trace - // events, so adding an event with a large amount of data could cause other - // trace event to be evicted. If a single trace is larger than the limit, it - // will cause all events to be evicted. The limit is set with the arg: - // GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE. + // A `Node` is created by calling `ChannelTrace::NewNode()` for a root-level + // event, or `Node::NewChild()` to create a child of an existing node. // - // TODO(ncteisen): as this call is used more and more throughout the gRPC - // stack, determine if it makes more sense to accept a char* instead of a - // slice. - void AddTraceEvent(Severity severity, const grpc_slice& data); - - // Adds a new trace event to the tracing object. This trace event refers to a - // an event that concerns a different channelz entity. For example, if this - // channel has created a new subchannel, then it would record that with - // a TraceEvent referencing the new subchannel. + // The `Node` object acts as a handle to an entry in the `ChannelTrace`. + // By default, a `Node` is temporary. If the `Node` object is destroyed + // (e.g., goes out of scope) without `Commit()` being called, the + // corresponding trace entry is removed from the `ChannelTrace`. This RAII + // behavior is useful for tracing events that might be cancelled or + // superseded. // - // NOTE: see the note in the method above. + // To make a trace entry permanent (until it's evicted by memory limits), + // call `Commit()` on the `Node` object. After `Commit()` is called, the + // `Node` object can be destroyed without affecting the trace entry. // - // TODO(ncteisen): see the todo in the method above. - void AddTraceEventWithReference(Severity severity, const grpc_slice& data, - RefCountedPtr referenced_entity); + // `Node` objects are move-only to ensure clear ownership of the trace entry + // handle. + // + // Example: + // ChannelTrace tracer(max_memory); + // // Create a root node + // auto root_node = tracer.NewNode("Root event"); + // // Create a child node + // auto child_node = root_node.NewChild("Child event: ", 123); + // // If something goes wrong before committing: + // if (error) { + // // child_node and root_node go out of scope, entries are removed + // return; + // } + // // Commit the nodes to make them permanent + // child_node.Commit(); + // root_node.Commit(); + class Node final { + public: + // Default constructor creates an invalid/sentinel Node. + // Operations on a default-constructed Node are no-ops or return + // invalid/sentinel results. + Node() : trace_(nullptr), ref_(EntryRef::Sentinel()) {} + Node(const Node&) = delete; + Node& operator=(const Node&) = delete; + Node(Node&& other) noexcept + : trace_(std::exchange(other.trace_, nullptr)), + ref_(other.ref_), + committed_(other.committed_) {} + Node& operator=(Node&& other) noexcept { + std::swap(trace_, other.trace_); + std::swap(ref_, other.ref_); + std::swap(committed_, other.committed_); + return *this; + } + // If the `Node` was not committed, its corresponding entry is removed + // from the `ChannelTrace`. + ~Node() { + if (trace_ != nullptr && !committed_ && ref_.id != kSentinelId) { + trace_->DropEntry(ref_); + } + } + + // Creates a new child node associated with this node. + // The child node will use the provided `renderer` to generate its + // description. + // Returns a new `Node` object representing the child. + // If this node is invalid (e.g., default-constructed or moved-from), + // an invalid `Node` is returned. + [[nodiscard]] Node NewNode(std::unique_ptr renderer) { + if (trace_ == nullptr || ref_.id == kSentinelId) return Node(); + return Node(trace_, trace_->AppendEntry(ref_, std::move(renderer))); + } + + // Creates a new child node associated with this node. + // The child node's description is formed by concatenating `args...`. + // Supported types for `args` are those compatible with `absl::StrCat` + // and `absl::string_view`. + // Returns a new `Node` object representing the child. + // If this node is invalid (e.g., default-constructed or moved-from), + // an invalid `Node` is returned. + template + [[nodiscard]] Node NewNode(Args&&... args) { + if (trace_ == nullptr || ref_.id == kSentinelId) return Node(); + return NewNode( + detail::RendererFromConcatenation(std::forward(args)...)); + } + + // Marks the trace entry associated with this `Node` as permanent. + // After `Commit()`, destroying this `Node` object will no longer remove + // the entry from the `ChannelTrace`. + // If the node is invalid, this is a no-op. + void Commit() { + if (trace_ == nullptr || ref_.id == kSentinelId) return; + committed_ = true; + } + + bool ProducesOutput() const { return ref_.id != kSentinelId; } + + private: + friend class ChannelTrace; + + Node(ChannelTrace* trace, EntryRef ref) : trace_(trace), ref_(ref) {} + + ChannelTrace* trace_; + EntryRef ref_; + bool committed_ = false; + }; + + [[nodiscard]] Node NewNode(std::unique_ptr render) { + return Node(this, AppendEntry(EntryRef::Sentinel(), std::move(render))); + } + + template + [[nodiscard]] Node NewNode(Args&&... args) { + return NewNode( + detail::RendererFromConcatenation(std::forward(args)...)); + } // Creates and returns the raw Json object, so a parent channelz // object may incorporate the json before rendering. Json RenderJson() const; void ForEachTraceEvent( - absl::FunctionRef)> - callback) const { - MutexLock lock(&mu_); - ForEachTraceEventLocked(callback); - } + absl::FunctionRef callback) const + ABSL_LOCKS_EXCLUDED(mu_); + + void Render(grpc_channelz_v2_Entity* entity, upb_Arena* arena) const; + + bool ProducesOutput() const { return max_memory_ > 0; } + std::string creation_timestamp() const; uint64_t num_events_logged() const { MutexLock lock(&mu_); @@ -112,58 +298,166 @@ class ChannelTrace { private: friend size_t testing::GetSizeofTraceEvent(void); - // Private class to encapsulate all the data and bookkeeping needed for a - // a trace event. - class TraceEvent { - public: - // Constructor for a TraceEvent that references a channel. - TraceEvent(Severity severity, const grpc_slice& data, - RefCountedPtr referenced_entity_); - - // Constructor for a TraceEvent that does not reverence a different - // channel. - TraceEvent(Severity severity, const grpc_slice& data); + void ForEachTraceEventLocked( + absl::FunctionRef callback) const + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); - ~TraceEvent(); + static constexpr uint16_t kSentinelId = 65535; - // set and get for the next_ pointer. - TraceEvent* next() const { return next_; } - void set_next(TraceEvent* next) { next_ = next; } + // Internal representation of a trace entry. + // These entries are stored in a std::vector `entries_` within ChannelTrace. + // They form a tree structure (parent/child/sibling links) and also a + // doubly-linked chronological list. + // + // The size of this struct is critical for memory management. + // `ChannelTrace` uses `sizeof(Entry)` to estimate memory usage and enforce + // `max_memory_`. Avoid adding fields or changing types that would + // significantly increase its size. The `uint16_t` types for IDs are used + // to keep the struct compact, limiting the total number of active (including + // free-list) entries to 65535. + struct Entry { + Timestamp when; // Timestamp of the event. + // A counter incremented each time an entry at a particular index in + // `entries_` is reused. Used by `EntryRef` to validate if a + // reference is still pointing to the same logical entry. + uint16_t salt = 0; + // Index of the parent entry in `entries_`, or `kSentinelId`. + uint16_t parent; + // Index of the first child of this entry, or `kSentinelId`. + uint16_t first_child; + // Index of the last child of this entry, or `kSentinelId`. + uint16_t last_child; + // Index of the previous sibling, or `kSentinelId`. + uint16_t prev_sibling; + // Index of the next sibling, or `kSentinelId`. + uint16_t next_sibling; + // Index of the previous entry in chronological order, or `kSentinelId`. + uint16_t prev_chronologically; + // Index of the next entry in chronological order, or `kSentinelId`. + uint16_t next_chronologically; + // Pointer to a Renderer object that can generate the string + // description for this trace event. + std::unique_ptr renderer; - size_t memory_usage() const { return memory_usage_; } - gpr_timespec timestamp() const { return timestamp_; } - Severity severity() const { return severity_; } - std::string description() const; - RefCountedPtr referenced_entity() const; + // The basic MemoryUsage function doesn't work reliably cross platform for + // std::unique_ptr within a struct. Open-code that part here. + size_t MemoryUsage() const { + if (renderer == nullptr) return sizeof(*this); + return MemoryUsageOf(*renderer) + sizeof(*this); + } + }; - private: - const gpr_timespec timestamp_; - const Severity severity_; - const grpc_slice data_; - const size_t memory_usage_; - // the tracer object for the (sub)channel that this trace event refers to. - const RefCountedPtr referenced_entity_; - TraceEvent* next_ = nullptr; - }; // TraceEvent - - // Internal helper to add and link in a trace event - void AddTraceEventHelper(TraceEvent* new_trace_event); - void ForEachTraceEventLocked( - absl::FunctionRef)>) const + EntryRef AppendEntry(EntryRef parent, std::unique_ptr renderer) + ABSL_LOCKS_EXCLUDED(mu_); + EntryRef NewEntry(EntryRef parent, std::unique_ptr renderer) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); + void DropEntry(EntryRef entry) ABSL_LOCKS_EXCLUDED(mu_); + void DropEntryId(uint16_t id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); - const size_t max_event_memory_; - const gpr_timespec time_created_; + void RenderEntry(const Entry& entry, + absl::FunctionRef callback, + int depth) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); + void RenderEntry(const Entry& entry, grpc_channelz_v2_TraceEvent* trace_event, + upb_Arena* arena) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); mutable Mutex mu_; + const Timestamp time_created_ = Timestamp::Now(); uint64_t num_events_logged_ ABSL_GUARDED_BY(mu_) = 0; - size_t event_list_memory_usage_ ABSL_GUARDED_BY(mu_) = 0; - TraceEvent* head_trace_ ABSL_GUARDED_BY(mu_) = nullptr; - TraceEvent* tail_trace_ ABSL_GUARDED_BY(mu_) = nullptr; + const uint32_t max_memory_; + uint32_t current_memory_ ABSL_GUARDED_BY(mu_) = 0; + uint16_t next_free_entry_ ABSL_GUARDED_BY(mu_) = kSentinelId; + uint16_t first_entry_ ABSL_GUARDED_BY(mu_) = kSentinelId; + uint16_t last_entry_ ABSL_GUARDED_BY(mu_) = kSentinelId; + std::vector entries_ ABSL_GUARDED_BY(mu_); }; +// A node that GRPC_CHANNELZ_TRACE can output to, that also +// logs to absl LOG(INFO) if a particular TraceFlag is enabled. +// Provides a way to elevate GRPC_TRACE_LOG statements to channelz +// also. +class TraceNode { + public: + TraceNode() = default; + + template + TraceNode(ChannelTrace::Node node, TraceFlag& flag, F prefix) + : node_(std::move(node)) { + if (GPR_UNLIKELY(flag.enabled())) { + log_to_absl_ = std::make_unique(prefix()); + } + } + + bool ProducesOutput() const { + return node_.ProducesOutput() || log_to_absl_ != nullptr; + } + + void Finish(std::unique_ptr renderer) { + if (GPR_UNLIKELY(log_to_absl_ != nullptr)) { + LOG(INFO) << *log_to_absl_ << renderer->Render(); + } + node_.NewNode(std::move(renderer)).Commit(); + } + + void Commit() { node_.Commit(); } + + private: + ChannelTrace::Node node_; + std::unique_ptr log_to_absl_; +}; + +namespace detail { +inline ChannelTrace* LogOutputFrom(ChannelTrace& t) { + if (!t.ProducesOutput()) return nullptr; + return &t; +} + +inline ChannelTrace::Node* LogOutputFrom(ChannelTrace::Node& n) { + if (!n.ProducesOutput()) return nullptr; + return &n; +} + +inline TraceNode* LogOutputFrom(TraceNode& n) { + if (!n.ProducesOutput()) return nullptr; + return &n; +} + +inline void OutputLogFromLogExpr(TraceNode* out, + std::unique_ptr renderer) { + out->Finish(std::move(renderer)); +} +} // namespace detail + } // namespace channelz } // namespace grpc_core +// Log like LOG() to a channelz object (and potentially as part of a GRPC_TRACE +// log with channelz::TraceNode). +// +// `output` is one of a ChannelTrace, ChannelTrace::Node or a TraceNode. +// +// This trace always commits - and the channelz node is inaccessible as a +// result. Use it for annotation like things, and if commit-ability is +// important, put it under a parent node and use that for `output`. +// +// Notes on this weird macro! +// - We want this to be a statement level thing, such that end of statement ==> +// we can commit the log line. +// - To do that we need to ensure we're not an expression, so we want an if, +// for, while, or do statement enclosing things. +// - But hey! we want to stream after the GRPC_CHANNELZ_LOG(foo), so we want an +// if right - if (we_can_output) output << s1 << s2 << s3; +// - But hey! now if someone copy/pastes this in front of an else then we +// bind with that else, and boom we've got a security hole... so let's not do +// that. +// - So, the for here acts as an if (the output = nullptr part ensures we don't) +// actually loop), ensures we have a statement, and ensures we don't +// accidentally bind with a trailing else. +// - And of course we skip wrapping things in {} because we really like that +// GRPC_CHANNELZ_LOG(foo) << "hello!"; syntax. +#define GRPC_CHANNELZ_LOG(output) \ + for (auto* out = grpc_core::channelz::detail::LogOutputFrom(output); \ + out != nullptr; out = nullptr) \ + grpc_core::channelz::detail::LogExpr< \ + std::remove_reference_t>(out) + #endif // GRPC_SRC_CORE_CHANNELZ_CHANNEL_TRACE_H diff --git a/deps/grpc/src/core/channelz/channelz.cc b/deps/grpc/src/core/channelz/channelz.cc index 57463527a7d..435c72a3c45 100644 --- a/deps/grpc/src/core/channelz/channelz.cc +++ b/deps/grpc/src/core/channelz/channelz.cc @@ -30,22 +30,28 @@ #include #include +#include "absl/cleanup/cleanup.h" #include "absl/log/check.h" #include "absl/status/statusor.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/strip.h" #include "src/core/channelz/channelz_registry.h" +#include "src/core/channelz/property_list.h" #include "src/core/lib/address_utils/parse_address.h" #include "src/core/lib/address_utils/sockaddr_utils.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/util/json/json_writer.h" +#include "src/core/util/notification.h" #include "src/core/util/string.h" #include "src/core/util/time.h" +#include "src/core/util/time_precise.h" +#include "src/core/util/upb_utils.h" #include "src/core/util/uri.h" #include "src/core/util/useful.h" +#include "src/proto/grpc/channelz/v2/channelz.upb.h" namespace grpc_core { namespace channelz { @@ -54,123 +60,54 @@ namespace channelz { // DataSink // -namespace { -class ChildObjectCollector { - public: - void Add(RefCountedPtr node) { - child_objects_[node->type()].insert(node->uuid()); - } - - void Add(std::vector> nodes) { - for (auto& node : nodes) Add(std::move(node)); - } - - // Calls AddAdditionalInfo to export the collected child objects. - void Finalize(DataSink& sink) { - if (child_objects_.empty()) return; - Json::Object subobjects; - for (const auto& [type, child_objects] : child_objects_) { - std::string key; - switch (type) { - case BaseNode::EntityType::kTopLevelChannel: - case BaseNode::EntityType::kSubchannel: - case BaseNode::EntityType::kListenSocket: - case BaseNode::EntityType::kServer: - case BaseNode::EntityType::kInternalChannel: { - LOG(ERROR) - << "Nodes of type " << BaseNode::EntityTypeString(type) - << " not supported for child object collection in DataSink"; - continue; - } - case BaseNode::EntityType::kSocket: - key = "subSockets"; - break; - case BaseNode::EntityType::kCall: - key = "calls"; - break; - } - Json::Array uuids; - uuids.reserve(child_objects.size()); - for (int64_t uuid : child_objects) { - uuids.push_back(Json::FromNumber(uuid)); - } - subobjects[key] = Json::FromArray(std::move(uuids)); - } - sink.AddAdditionalInfo("childObjects", std::move(subobjects)); - } - - private: - std::map> child_objects_; -}; - -class JsonDataSink final : public DataSink { - public: - explicit JsonDataSink(Json::Object& output) : output_(output) { - CHECK(output_.find("additionalInfo") == output_.end()); - } - ~JsonDataSink() { - collector_.Finalize(*this); - if (additional_info_ != nullptr) { - output_["additionalInfo"] = - Json::FromObject(std::move(*additional_info_)); - } - } - - void AddAdditionalInfo(absl::string_view name, - Json::Object additional_info) override { - if (additional_info_ == nullptr) { - additional_info_ = std::make_unique(); - } - additional_info_->emplace(name, - Json::FromObject(std::move(additional_info))); - } - - void AddChildObjects( - std::vector> child_objects) override { - collector_.Add(std::move(child_objects)); - } - - private: - Json::Object& output_; - std::unique_ptr additional_info_; - ChildObjectCollector collector_; -}; - -class ExplicitJsonDataSink final : public DataSink { - public: - void AddAdditionalInfo(absl::string_view name, - Json::Object additional_info) override { - additional_info_.emplace(name, - Json::FromObject(std::move(additional_info))); - } +void DataSinkImplementation::AddData(absl::string_view name, + std::unique_ptr data) { + MutexLock lock(&mu_); + additional_info_.emplace(name, std::move(data)); +} - void AddChildObjects( - std::vector> child_objects) override { - collector_.Add(std::move(child_objects)); +Json::Object DataSinkImplementation::Finalize(bool) { + MutexLock lock(&mu_); + Json::Object out; + for (auto& [name, additional_info] : additional_info_) { + out[name] = Json::FromObject(additional_info->ToJson()); } + return out; +} - Json::Object Finalize() { - collector_.Finalize(*this); - return std::move(additional_info_); +void DataSinkImplementation::Finalize(bool timed_out, + grpc_channelz_v2_Entity* entity, + upb_Arena* arena) { + MutexLock lock(&mu_); + grpc_channelz_v2_Entity_set_timed_out(entity, timed_out); + for (auto& [name, additional_info] : additional_info_) { + auto* staple = grpc_channelz_v2_Entity_add_data(entity, arena); + grpc_channelz_v2_Data_set_name(staple, + CopyStdStringToUpbString(name, arena)); + additional_info->FillProto( + grpc_channelz_v2_Data_mutable_value(staple, arena), arena); } - - private: - Json::Object additional_info_; - ChildObjectCollector collector_; -}; -} // namespace +} // // BaseNode // -BaseNode::BaseNode(EntityType type, std::string name) - : type_(type), uuid_(-1), name_(std::move(name)) { - // The registry will set uuid_ under its lock. +BaseNode::BaseNode(EntityType type, size_t max_trace_memory, std::string name) + : type_(type), + uuid_(-1), + name_(std::move(name)), + trace_(max_trace_memory) {} + +void BaseNode::NodeConstructed() { + node_constructed_called_ = true; ChannelzRegistry::Register(this); } -void BaseNode::Orphaned() { ChannelzRegistry::Unregister(this); } +void BaseNode::Orphaned() { + DCHECK(node_constructed_called_); + ChannelzRegistry::Unregister(this); +} intptr_t BaseNode::UuidSlow() { return ChannelzRegistry::NumberNode(this); } @@ -180,20 +117,25 @@ std::string BaseNode::RenderJsonString() { } void BaseNode::PopulateJsonFromDataSources(Json::Object& json) { - JsonDataSink sink(json); - MutexLock lock(&data_sources_mu_); - for (DataSource* data_source : data_sources_) { - data_source->AddData(sink); - } + auto info = AdditionalInfo(); + if (info.empty()) return; + json["additionalInfo"] = Json::FromObject(std::move(info)); } Json::Object BaseNode::AdditionalInfo() { - ExplicitJsonDataSink sink; - MutexLock lock(&data_sources_mu_); - for (DataSource* data_source : data_sources_) { - data_source->AddData(sink); + auto done = std::make_shared(); + auto sink_impl = std::make_shared(); + { + MutexLock lock(&data_sources_mu_); + auto done_notifier = std::make_shared( + [done]() { done->Notify(); }); + for (DataSource* data_source : data_sources_) { + data_source->AddData(DataSink(sink_impl, done_notifier)); + } } - return sink.Finalize(); + bool completed = + done->WaitForNotificationWithTimeout(absl::Milliseconds(100)); + return sink_impl->Finalize(!completed); } void BaseNode::RunZTrace( @@ -235,28 +177,86 @@ void BaseNode::RunZTrace( ztrace->Run(deadline, std::move(args), event_engine, std::move(callback)); } +void BaseNode::SerializeEntity(grpc_channelz_v2_Entity* entity, + upb_Arena* arena) { + grpc_channelz_v2_Entity_set_id(entity, uuid()); + grpc_channelz_v2_Entity_set_kind( + entity, StdStringToUpbString(EntityTypeToKind(type_))); + { + MutexLock lock(&parent_mu_); + auto* parents = + grpc_channelz_v2_Entity_resize_parents(entity, parents_.size(), arena); + for (const auto& parent : parents_) { + *parents++ = parent->uuid(); + } + } + grpc_channelz_v2_Entity_set_orphaned(entity, orphaned_index_ != 0); + + auto done = std::make_shared(); + auto sink_impl = std::make_shared(); + auto done_notifier = std::make_shared( + [done]() { done->Notify(); }); + auto make_data_sink = [sink_impl, done_notifier]() { + return DataSink(sink_impl, done_notifier); + }; + AddNodeSpecificData(make_data_sink()); + { + MutexLock lock(&data_sources_mu_); + for (DataSource* data_source : data_sources_) { + data_source->AddData(make_data_sink()); + } + } + bool completed = + done->WaitForNotificationWithTimeout(absl::Milliseconds(100)); + sink_impl->Finalize(!completed, entity, arena); + + trace_.Render(entity, arena); +} + +void BaseNode::AddNodeSpecificData(DataSink) { + // Default implementation does nothing. +} + +std::string BaseNode::SerializeEntityToString() { + upb_Arena* arena = upb_Arena_New(); + auto cleanup = absl::MakeCleanup([arena]() { upb_Arena_Free(arena); }); + grpc_channelz_v2_Entity* entity = grpc_channelz_v2_Entity_new(arena); + SerializeEntity(entity, arena); + size_t length; + auto* bytes = grpc_channelz_v2_Entity_serialize(entity, arena, &length); + return std::string(bytes, length); +} + // // DataSource // -DataSource::DataSource(RefCountedPtr node) : node_(std::move(node)) { - if (node_ == nullptr) return; - MutexLock lock(&node_->data_sources_mu_); - node_->data_sources_.push_back(this); -} +DataSource::DataSource(RefCountedPtr node) : node_(std::move(node)) {} DataSource::~DataSource() { DCHECK(node_ == nullptr) << "DataSource must be ResetDataSource()'d in the " "most derived class before destruction"; } -void DataSource::ResetDataSource() { +void DataSource::SourceConstructed() { + if (node_ == nullptr) return; + MutexLock lock(&node_->data_sources_mu_); + node_->data_sources_.push_back(this); +} + +void DataSource::SourceDestructing() { RefCountedPtr node = std::move(node_); if (node == nullptr) return; MutexLock lock(&node->data_sources_mu_); - node->data_sources_.erase( - std::remove(node->data_sources_.begin(), node->data_sources_.end(), this), - node->data_sources_.end()); + for (size_t i = 0; i < node->data_sources_.size(); ++i) { + if (node->data_sources_[i] == this) { + std::swap(node->data_sources_[i], node->data_sources_.back()); + node->data_sources_.pop_back(); + return; + } + } + LOG(DFATAL) << "DataSource not found in node's data sources -- probably " + "SourceConstructed was not called"; } // @@ -295,6 +295,17 @@ void CallCounts::PopulateJson(Json::Object& json) const { } } +PropertyList CallCounts::ToPropertyList() const { + return PropertyList() + .Set("calls_started", calls_started) + .Set("calls_succeeded", calls_succeeded) + .Set("calls_failed", calls_failed) + .Set("last_call_started_timestamp", [this]() -> std::optional { + if (last_call_started_cycle == 0) return std::nullopt; + return Timestamp::FromCycleCounterRoundDown(last_call_started_cycle); + }()); +} + // // PerCpuCallCountingHelper // @@ -335,13 +346,14 @@ CallCounts PerCpuCallCountingHelper::GetCallCounts() const { // ChannelNode // -ChannelNode::ChannelNode(std::string target, size_t channel_tracer_max_nodes, +ChannelNode::ChannelNode(std::string target, size_t max_trace_memory, bool is_internal_channel) : BaseNode(is_internal_channel ? EntityType::kInternalChannel : EntityType::kTopLevelChannel, - target), - target_(std::move(target)), - trace_(channel_tracer_max_nodes) {} + max_trace_memory, target), + target_(std::move(target)) { + NodeConstructed(); +} const char* ChannelNode::GetChannelConnectivityStateChangeString( grpc_connectivity_state state) { @@ -405,7 +417,7 @@ Json ChannelNode::RenderJson() { }); } // Fill in the channel trace if applicable. - Json trace_json = trace_.RenderJson(); + Json trace_json = trace().RenderJson(); if (trace_json.type() != Json::Type::kNull) { data["trace"] = std::move(trace_json); } @@ -425,6 +437,14 @@ Json ChannelNode::RenderJson() { return Json::FromObject(std::move(json)); } +void ChannelNode::AddNodeSpecificData(DataSink sink) { + sink.AddData("channel", PropertyList() + .Set("target", target_) + .Set("connectivity_state", connectivity_state())); + sink.AddData("call_counts", call_counter_.GetCallCounts().ToPropertyList()); + sink.AddData("channel_args", channel_args_.ToPropertyList()); +} + void ChannelNode::PopulateChildRefs(Json::Object* json) { auto child_subchannels = this->child_subchannels(); auto child_channels = this->child_channels(); @@ -459,10 +479,11 @@ void ChannelNode::SetConnectivityState(grpc_connectivity_state state) { // SubchannelNode::SubchannelNode(std::string target_address, - size_t channel_tracer_max_nodes) - : BaseNode(EntityType::kSubchannel, target_address), - target_(std::move(target_address)), - trace_(channel_tracer_max_nodes) {} + size_t max_trace_memory) + : BaseNode(EntityType::kSubchannel, max_trace_memory, target_address), + target_(std::move(target_address)) { + NodeConstructed(); +} SubchannelNode::~SubchannelNode() {} @@ -472,7 +493,8 @@ void SubchannelNode::UpdateConnectivityState(grpc_connectivity_state state) { void SubchannelNode::SetChildSocket(RefCountedPtr socket) { MutexLock lock(&socket_mu_); - child_socket_ = std::move(socket); + child_socket_ = + socket == nullptr ? nullptr : socket->WeakRefAsSubclass(); } std::string SubchannelNode::connectivity_state() const { @@ -490,7 +512,7 @@ Json SubchannelNode::RenderJson() { {"target", Json::FromString(target_)}, }; // Fill in the channel trace if applicable - Json trace_json = trace_.RenderJson(); + Json trace_json = trace().RenderJson(); if (trace_json.type() != Json::Type::kNull) { data["trace"] = std::move(trace_json); } @@ -504,7 +526,7 @@ Json SubchannelNode::RenderJson() { {"data", Json::FromObject(std::move(data))}, }; // Populate the child socket. - RefCountedPtr child_socket; + WeakRefCountedPtr child_socket; { MutexLock lock(&socket_mu_); child_socket = child_socket_; @@ -521,12 +543,22 @@ Json SubchannelNode::RenderJson() { return Json::FromObject(std::move(object)); } +void SubchannelNode::AddNodeSpecificData(DataSink sink) { + sink.AddData("channel", PropertyList() + .Set("target", target_) + .Set("connectivity_state", connectivity_state())); + sink.AddData("call_counts", call_counter_.GetCallCounts().ToPropertyList()); + sink.AddData("channel_args", channel_args_.ToPropertyList()); +} + // // ServerNode // -ServerNode::ServerNode(size_t channel_tracer_max_nodes) - : BaseNode(EntityType::kServer, ""), trace_(channel_tracer_max_nodes) {} +ServerNode::ServerNode(size_t max_trace_memory) + : BaseNode(EntityType::kServer, max_trace_memory, "") { + NodeConstructed(); +} ServerNode::~ServerNode() {} @@ -555,7 +587,7 @@ std::string ServerNode::RenderServerSockets(intptr_t start_socket_id, Json ServerNode::RenderJson() { Json::Object data; // Fill in the channel trace if applicable. - Json trace_json = trace_.RenderJson(); + Json trace_json = trace().RenderJson(); if (trace_json.type() != Json::Type::kNull) { data["trace"] = std::move(trace_json); } @@ -586,26 +618,31 @@ Json ServerNode::RenderJson() { return Json::FromObject(std::move(object)); } -std::map> +void ServerNode::AddNodeSpecificData(DataSink sink) { + sink.AddData("call_counts", call_counter_.GetCallCounts().ToPropertyList()); + sink.AddData("channel_args", channel_args_.ToPropertyList()); +} + +std::map> ServerNode::child_listen_sockets() const { - std::map> result; + std::map> result; auto [children, _] = ChannelzRegistry::GetChildrenOfType( 0, this, BaseNode::EntityType::kListenSocket, std::numeric_limits::max()); for (const auto& child : children) { - result[child->uuid()] = child->RefAsSubclass(); + result[child->uuid()] = child->WeakRefAsSubclass(); } return result; } -std::map> ServerNode::child_sockets() +std::map> ServerNode::child_sockets() const { - std::map> result; + std::map> result; auto [children, _] = ChannelzRegistry::GetChildrenOfType( 0, this, BaseNode::EntityType::kSocket, std::numeric_limits::max()); for (const auto& child : children) { - result[child->uuid()] = child->RefAsSubclass(); + result[child->uuid()] = child->WeakRefAsSubclass(); } return result; } @@ -632,6 +669,27 @@ Json SocketNode::Security::Tls::RenderJson() { return Json::FromObject(std::move(data)); } +PropertyList SocketNode::Security::Tls::ToPropertyList() const { + PropertyList result; + switch (type) { + case NameType::kUnset: + break; + case NameType::kStandardName: + result.Set("standard_name", name); + break; + case NameType::kOtherName: + result.Set("other_name", name); + break; + } + if (!local_certificate.empty()) { + result.Set("local_certificate", absl::Base64Escape(local_certificate)); + } + if (!remote_certificate.empty()) { + result.Set("remote_certificate", absl::Base64Escape(remote_certificate)); + } + return result; +} + // // SocketNode::Security // @@ -655,38 +713,22 @@ Json SocketNode::Security::RenderJson() { return Json::FromObject(std::move(data)); } -namespace { - -void* SecurityArgCopy(void* p) { - SocketNode::Security* xds_certificate_provider = - static_cast(p); - return xds_certificate_provider->Ref().release(); -} - -void SecurityArgDestroy(void* p) { - SocketNode::Security* xds_certificate_provider = - static_cast(p); - xds_certificate_provider->Unref(); -} - -int SecurityArgCmp(void* p, void* q) { return QsortCompare(p, q); } - -const grpc_arg_pointer_vtable kChannelArgVtable = { - SecurityArgCopy, SecurityArgDestroy, SecurityArgCmp}; - -} // namespace - -grpc_arg SocketNode::Security::MakeChannelArg() const { - return grpc_channel_arg_pointer_create( - const_cast(GRPC_ARG_CHANNELZ_SECURITY), - const_cast(this), &kChannelArgVtable); -} - -RefCountedPtr SocketNode::Security::GetFromChannelArgs( - const grpc_channel_args* args) { - Security* security = grpc_channel_args_find_pointer( - args, GRPC_ARG_CHANNELZ_SECURITY); - return security != nullptr ? security->Ref() : nullptr; +PropertyList SocketNode::Security::ToPropertyList() const { + switch (type) { + case ModelType::kUnset: + break; + case ModelType::kTls: + if (tls) { + return tls->ToPropertyList(); + } + break; + case ModelType::kOther: + if (other.has_value()) { + return PropertyList().Set("other", JsonDump(*other)); + } + break; + } + return PropertyList(); } // @@ -736,10 +778,12 @@ void PopulateSocketAddressJson(Json::Object* json, const char* name, SocketNode::SocketNode(std::string local, std::string remote, std::string name, RefCountedPtr security) - : BaseNode(EntityType::kSocket, std::move(name)), + : BaseNode(EntityType::kSocket, 0, std::move(name)), local_(std::move(local)), remote_(std::move(remote)), - security_(std::move(security)) {} + security_(std::move(security)) { + NodeConstructed(); +} void SocketNode::RecordStreamStartedFromLocal() { streams_started_.fetch_add(1, std::memory_order_relaxed); @@ -845,13 +889,54 @@ Json SocketNode::RenderJson() { return Json::FromObject(std::move(object)); } +void SocketNode::AddNodeSpecificData(DataSink sink) { + auto convert_cycle_counter = + [](gpr_cycle_counter cycle_counter) -> std::optional { + if (cycle_counter == 0) return std::nullopt; + return Timestamp::FromCycleCounterRoundDown(cycle_counter); + }; + sink.AddData("socket", + PropertyList().Set("local", local_).Set("remote", remote_)); + sink.AddData( + "call_counts", + PropertyList() + .Set("streams_started", + streams_started_.load(std::memory_order_relaxed)) + .Set("streams_succeeded", + streams_succeeded_.load(std::memory_order_relaxed)) + .Set("streams_failed", + streams_failed_.load(std::memory_order_relaxed)) + .Set("messages_sent", messages_sent_.load(std::memory_order_relaxed)) + .Set("messages_received", + messages_received_.load(std::memory_order_relaxed)) + .Set("keepalives_sent", + keepalives_sent_.load(std::memory_order_relaxed)) + .Set("last_local_stream_created_timestamp", + convert_cycle_counter(last_local_stream_created_cycle_.load( + std::memory_order_relaxed))) + .Set("last_remote_stream_created_timestamp", + convert_cycle_counter(last_remote_stream_created_cycle_.load( + std::memory_order_relaxed))) + .Set("last_message_sent_timestamp", + convert_cycle_counter( + last_message_sent_cycle_.load(std::memory_order_relaxed))) + .Set("last_message_received_timestamp", + convert_cycle_counter(last_message_received_cycle_.load( + std::memory_order_relaxed)))); + if (security_ != nullptr) { + sink.AddData("security", security_->ToPropertyList()); + } +} + // // ListenSocketNode // ListenSocketNode::ListenSocketNode(std::string local_addr, std::string name) - : BaseNode(EntityType::kListenSocket, std::move(name)), - local_addr_(std::move(local_addr)) {} + : BaseNode(EntityType::kListenSocket, 0, std::move(name)), + local_addr_(std::move(local_addr)) { + NodeConstructed(); +} Json ListenSocketNode::RenderJson() { Json::Object object = { @@ -865,6 +950,10 @@ Json ListenSocketNode::RenderJson() { return Json::FromObject(std::move(object)); } +void ListenSocketNode::AddNodeSpecificData(DataSink sink) { + sink.AddData("listen_socket", PropertyList().Set("local", local_addr_)); +} + // // CallNode // diff --git a/deps/grpc/src/core/channelz/channelz.h b/deps/grpc/src/core/channelz/channelz.h index b54e76812bc..1de049c5c27 100644 --- a/deps/grpc/src/core/channelz/channelz.h +++ b/deps/grpc/src/core/channelz/channelz.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "absl/base/thread_annotations.h" @@ -50,6 +51,7 @@ #include "src/core/util/time.h" #include "src/core/util/time_precise.h" #include "src/core/util/useful.h" +#include "src/proto/grpc/channelz/v2/channelz.upb.h" // Channel arg key for channelz node. #define GRPC_ARG_CHANNELZ_CHANNEL_NODE \ @@ -80,6 +82,8 @@ namespace channelz { class SocketNode; class ListenSocketNode; class DataSource; +class DataSink; +class PropertyList; class ZTrace; namespace testing { @@ -123,8 +127,42 @@ class BaseNode : public DualRefCounted { return "unknown"; } + static absl::string_view EntityTypeToKind(EntityType type) { + switch (type) { + case EntityType::kTopLevelChannel: + return "channel"; + case EntityType::kInternalChannel: + return "internal_channel"; + case EntityType::kSubchannel: + return "subchannel"; + case EntityType::kServer: + return "server"; + case EntityType::kListenSocket: + return "listen_socket"; + case EntityType::kSocket: + return "socket"; + case EntityType::kCall: + return "call"; + } + } + + static std::optional KindToEntityType(absl::string_view kind) { + if (kind == "channel") return EntityType::kTopLevelChannel; + if (kind == "internal_channel") return EntityType::kInternalChannel; + if (kind == "subchannel") return EntityType::kSubchannel; + if (kind == "server") return EntityType::kServer; + if (kind == "listen_socket") return EntityType::kListenSocket; + if (kind == "socket") return EntityType::kSocket; + if (kind == "call") return EntityType::kCall; + return std::nullopt; + } + protected: - BaseNode(EntityType type, std::string name); + BaseNode(EntityType type, size_t max_trace_memory, std::string name); + + // Leaf derived types should call NodeConstructed() in their constructors + // to complete the initialization. + void NodeConstructed(); public: void Orphaned() override; @@ -173,8 +211,25 @@ class BaseNode : public DualRefCounted { absl::AnyInvocable callback); Json::Object AdditionalInfo(); + const ChannelTrace& trace() const { return trace_; } + template + ChannelTrace::Node NewTraceNode(Args&&... args) { + return trace_.NewNode(std::forward(args)...); + } + ChannelTrace& mutable_trace() { return trace_; } + + void SerializeEntity(grpc_channelz_v2_Entity* entity, upb_Arena* arena); + + std::string SerializeEntityToString(); + protected: void PopulateJsonFromDataSources(Json::Object& json); + // V2: Add any node-specific data to the sink. + // This is information that used to be provided by overloaded RenderJson + // methods. + // Over time the hope is that we can eliminate this method and move all + // functionality into data sources. + virtual void AddNodeSpecificData(DataSink sink); private: // to allow the ChannelzRegistry to set uuid_ under its lock. @@ -188,6 +243,7 @@ class BaseNode : public DualRefCounted { intptr_t UuidSlow(); const EntityType type_; + bool node_constructed_called_ = false; uint64_t orphaned_index_ = 0; // updated by registry std::atomic uuid_; std::string name_; @@ -198,8 +254,22 @@ class BaseNode : public DualRefCounted { BaseNode* next_; // updated by registry mutable Mutex parent_mu_; ParentSet parents_ ABSL_GUARDED_BY(parent_mu_); + ChannelTrace trace_; }; +namespace detail { +inline ChannelTrace* LogOutputFrom(BaseNode* n) { + if (n == nullptr) return nullptr; + return LogOutputFrom(n->mutable_trace()); +} + +template +inline std::enable_if_t, ChannelTrace*> +LogOutputFrom(const RefCountedPtr& n) { + return LogOutputFrom(n.get()); +} +} // namespace detail + class ZTrace { public: virtual ~ZTrace() = default; @@ -209,15 +279,79 @@ class ZTrace { absl::AnyInvocable) = 0; }; +// This class is used to collect additional information about the channelz +// node. It's the backing implementation for DataSink. channelz users should +// use DataSink instead of this class directly. +// We form a shared_ptr<> around this class during collection. +// In DataSink we use a weak_ptr<> to allow rapid resource reclamation once +// the collection is complete (or has timed out). +class DataSinkImplementation { + public: + class Data { + public: + virtual ~Data() = default; + virtual Json::Object ToJson() = 0; + virtual void FillProto(google_protobuf_Any* any, upb_Arena* arena) = 0; + }; + + void AddData(absl::string_view name, std::unique_ptr data); + Json::Object Finalize(bool timed_out); + void Finalize(bool timed_out, grpc_channelz_v2_Entity* entity, + upb_Arena* arena); + + private: + Mutex mu_; + std::map> additional_info_ + ABSL_GUARDED_BY(mu_); +}; + +// Wrapper around absl::AnyInvocable that is used to notify when the +// DataSink has completed. +// We hold a shared_ptr<> around this class in DataSink to keep knowledge of +// when the DataSink has completed. +class DataSinkCompletionNotification { + public: + explicit DataSinkCompletionNotification(absl::AnyInvocable callback) + : callback_(std::move(callback)) {} + ~DataSinkCompletionNotification() { callback_(); } + + private: + absl::AnyInvocable callback_; +}; + class DataSink { public: - virtual void AddAdditionalInfo(absl::string_view name, - Json::Object additional_info) = 0; - virtual void AddChildObjects( - std::vector> children) = 0; + DataSink(std::shared_ptr impl, + std::shared_ptr notification) + : impl_(impl), notification_(std::move(notification)) {} + + template + std::void_t().TakeJsonObject())> AddData( + absl::string_view name, T value) { + class DataImpl final : public DataSinkImplementation::Data { + public: + explicit DataImpl(T value) : value_(std::move(value)) {} + Json::Object ToJson() override { return value_.TakeJsonObject(); } + void FillProto(google_protobuf_Any* any, upb_Arena* arena) override { + value_.FillAny(any, arena); + } + + private: + T value_; + }; + AddData(name, std::make_unique(std::move(value))); + } - protected: - ~DataSink() = default; + private: + void AddData(absl::string_view name, + std::unique_ptr data) { + auto impl = impl_.lock(); + if (impl == nullptr) return; + impl->AddData(name, std::move(data)); + } + + std::weak_ptr impl_; + std::shared_ptr notification_; }; class DataSource { @@ -227,7 +361,7 @@ class DataSource { // Add any relevant json fragments to the output. // This method must not cause the DataSource to be deleted, or else there will // be a deadlock. - virtual void AddData(DataSink&) {} + virtual void AddData(DataSink) {} // If this data source exports some ztrace, return it here. virtual std::unique_ptr GetZTrace(absl::string_view /*name*/) { @@ -238,11 +372,15 @@ class DataSource { ~DataSource(); RefCountedPtr channelz_node() { return node_; } + // This method must be called in the most derived class's constructor. + // It adds this data source to the node's list of data sources. + void SourceConstructed(); + // This method must be called in the most derived class's destructor. // It removes this data source from the node's list of data sources. // If it is not called, then the AddData() function pointer may be invalid // when the node is queried. - void ResetDataSource(); + void SourceDestructing(); private: RefCountedPtr node_; @@ -260,6 +398,7 @@ struct CallCounts { } void PopulateJson(Json::Object& json) const; + PropertyList ToPropertyList() const; }; // This class is a helper class for channelz entities that deal with Channels, @@ -319,7 +458,7 @@ class PerCpuCallCountingHelper final { // Handles channelz bookkeeping for channels class ChannelNode final : public BaseNode { public: - ChannelNode(std::string target, size_t channel_tracer_max_nodes, + ChannelNode(std::string target, size_t max_trace_memory, bool is_internal_channel); void Orphaned() override { @@ -341,15 +480,6 @@ class ChannelNode final : public BaseNode { Json RenderJson() override; // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { - trace_.AddTraceEvent(severity, data); - } - void AddTraceEventWithReference(ChannelTrace::Severity severity, - const grpc_slice& data, - RefCountedPtr referenced_channel) { - trace_.AddTraceEventWithReference(severity, data, - std::move(referenced_channel)); - } void SetChannelArgs(const ChannelArgs& channel_args) { channel_args_ = channel_args; } @@ -364,15 +494,14 @@ class ChannelNode final : public BaseNode { CallCounts GetCallCounts() const { return call_counter_.GetCallCounts(); } std::set child_channels() const; std::set child_subchannels() const; - const ChannelTrace& trace() const { return trace_; } const ChannelArgs& channel_args() const { return channel_args_; } private: void PopulateChildRefs(Json::Object* json); + void AddNodeSpecificData(DataSink sink) override; std::string target_; CallCountingHelper call_counter_; - ChannelTrace trace_; // TODO(ctiller): keeping channel args here can create odd circular references // that are hard to reason about. Consider moving this to a DataSource. ChannelArgs channel_args_; @@ -385,7 +514,7 @@ class ChannelNode final : public BaseNode { // Handles channelz bookkeeping for subchannels class SubchannelNode final : public BaseNode { public: - SubchannelNode(std::string target_address, size_t channel_tracer_max_nodes); + SubchannelNode(std::string target_address, size_t max_trace_memory); ~SubchannelNode() override; void Orphaned() override { @@ -404,18 +533,9 @@ class SubchannelNode final : public BaseNode { Json RenderJson() override; // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { - trace_.AddTraceEvent(severity, data); - } void SetChannelArgs(const ChannelArgs& channel_args) { channel_args_ = channel_args; } - void AddTraceEventWithReference(ChannelTrace::Severity severity, - const grpc_slice& data, - RefCountedPtr referenced_channel) { - trace_.AddTraceEventWithReference(severity, data, - std::move(referenced_channel)); - } void RecordCallStarted() { call_counter_.RecordCallStarted(); } void RecordCallFailed() { call_counter_.RecordCallFailed(); } void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } @@ -423,23 +543,23 @@ class SubchannelNode final : public BaseNode { const std::string& target() const { return target_; } std::string connectivity_state() const; CallCounts GetCallCounts() const { return call_counter_.GetCallCounts(); } - RefCountedPtr child_socket() const { + WeakRefCountedPtr child_socket() const { MutexLock lock(&socket_mu_); return child_socket_; } - const ChannelTrace& trace() const { return trace_; } const ChannelArgs& channel_args() const { return channel_args_; } private: + void AddNodeSpecificData(DataSink sink) override; + // Allows the channel trace test to access trace_. friend class testing::SubchannelNodePeer; std::atomic connectivity_state_{GRPC_CHANNEL_IDLE}; mutable Mutex socket_mu_; - RefCountedPtr child_socket_ ABSL_GUARDED_BY(socket_mu_); + WeakRefCountedPtr child_socket_ ABSL_GUARDED_BY(socket_mu_); std::string target_; CallCountingHelper call_counter_; - ChannelTrace trace_; // TODO(ctiller): keeping channel args here can create odd circular references // that are hard to reason about. Consider moving this to a DataSource. ChannelArgs channel_args_; @@ -448,7 +568,7 @@ class SubchannelNode final : public BaseNode { // Handles channelz bookkeeping for servers class ServerNode final : public BaseNode { public: - explicit ServerNode(size_t channel_tracer_max_nodes); + explicit ServerNode(size_t max_trace_memory); ~ServerNode() override; @@ -463,15 +583,6 @@ class ServerNode final : public BaseNode { intptr_t max_results); // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { - trace_.AddTraceEvent(severity, data); - } - void AddTraceEventWithReference(ChannelTrace::Severity severity, - const grpc_slice& data, - RefCountedPtr referenced_channel) { - trace_.AddTraceEventWithReference(severity, data, - std::move(referenced_channel)); - } void SetChannelArgs(const ChannelArgs& channel_args) { channel_args_ = channel_args; } @@ -481,16 +592,16 @@ class ServerNode final : public BaseNode { CallCounts GetCallCounts() const { return call_counter_.GetCallCounts(); } - std::map> child_listen_sockets() + std::map> child_listen_sockets() const; - std::map> child_sockets() const; + std::map> child_sockets() const; - const ChannelTrace& trace() const { return trace_; } const ChannelArgs& channel_args() const { return channel_args_; } private: + void AddNodeSpecificData(DataSink sink) override; + PerCpuCallCountingHelper call_counter_; - ChannelTrace trace_; // TODO(ctiller): keeping channel args here can create odd circular references // that are hard to reason about. Consider moving this to a DataSource. ChannelArgs channel_args_; @@ -514,6 +625,7 @@ class SocketNode final : public BaseNode { std::string remote_certificate; Json RenderJson(); + PropertyList ToPropertyList() const; }; enum class ModelType { kUnset = 0, kTls = 1, kOther = 2 }; ModelType type = ModelType::kUnset; @@ -521,6 +633,7 @@ class SocketNode final : public BaseNode { std::optional other; Json RenderJson(); + PropertyList ToPropertyList() const; static absl::string_view ChannelArgName() { return GRPC_ARG_CHANNELZ_SECURITY; @@ -529,11 +642,6 @@ class SocketNode final : public BaseNode { static int ChannelArgsCompare(const Security* a, const Security* b) { return QsortCompare(a, b); } - - grpc_arg MakeChannelArg() const; - - static RefCountedPtr GetFromChannelArgs( - const grpc_channel_args* args); }; SocketNode(std::string local, std::string remote, std::string name, @@ -602,6 +710,7 @@ class SocketNode final : public BaseNode { gpr_cycle_counter cycle_counter) const { return gpr_format_timespec(gpr_cycle_counter_to_time(cycle_counter)); } + void AddNodeSpecificData(DataSink sink) override; std::atomic streams_started_{0}; std::atomic streams_succeeded_{0}; @@ -627,13 +736,17 @@ class ListenSocketNode final : public BaseNode { Json RenderJson() override; private: + void AddNodeSpecificData(DataSink sink) override; + std::string local_addr_; }; class CallNode final : public BaseNode { public: explicit CallNode(std::string name) - : BaseNode(EntityType::kCall, std::move(name)) {} + : BaseNode(EntityType::kCall, 0, std::move(name)) { + NodeConstructed(); + } Json RenderJson() override; }; diff --git a/deps/grpc/src/core/channelz/channelz_registry.cc b/deps/grpc/src/core/channelz/channelz_registry.cc index 021b695fb39..393b7e7f447 100644 --- a/deps/grpc/src/core/channelz/channelz_registry.cc +++ b/deps/grpc/src/core/channelz/channelz_registry.cc @@ -288,7 +288,8 @@ WeakRefCountedPtr ChannelzRegistry::InternalGet(intptr_t uuid) { intptr_t ChannelzRegistry::InternalNumberNode(BaseNode* node) { // node must be strongly owned still - node->AssertStronglyOwned(); + auto strong_node = node->RefIfNonZero(); + if (strong_node == nullptr) return 0; const size_t node_shard_index = NodeShardIndex(node); NodeShard& node_shard = node_shards_[node_shard_index]; MutexLock index_lock(&index_mu_); diff --git a/deps/grpc/src/core/channelz/channelz_registry.h b/deps/grpc/src/core/channelz/channelz_registry.h index cc9af1cb87b..667c13fd5a5 100644 --- a/deps/grpc/src/core/channelz/channelz_registry.h +++ b/deps/grpc/src/core/channelz/channelz_registry.h @@ -89,6 +89,12 @@ class ChannelzRegistry final { start_channel_id); } + static auto GetTopSockets(intptr_t start_socket_id) { + return Default() + ->InternalGetObjects( + start_socket_id); + } + static std::string GetTopChannelsJson(intptr_t start_channel_id); static std::string GetServersJson(intptr_t start_server_id); @@ -107,6 +113,16 @@ class ChannelzRegistry final { max_results); } + static WeakRefCountedPtr GetNode(intptr_t uuid) { + return Default()->InternalGet(uuid); + } + + static std::tuple>, bool> + GetNodesOfType(intptr_t start_node, BaseNode::EntityType type, + size_t max_results) { + return Default()->InternalGetNodesOfType(start_node, type, max_results); + } + // Test only helper function to dump the JSON representation to std out. // This can aid in debugging channelz code. static void LogAllEntities() { Default()->InternalLogAllEntities(); } @@ -210,6 +226,14 @@ class ChannelzRegistry final { max_results); } + std::tuple>, bool> + InternalGetNodesOfType(intptr_t start_node, BaseNode::EntityType type, + size_t max_results) { + return QueryNodes( + start_node, [type](const BaseNode* n) { return n->type() == type; }, + max_results); + } + template WeakRefCountedPtr InternalGetTyped(intptr_t uuid) { WeakRefCountedPtr node = InternalGet(uuid); diff --git a/deps/grpc/src/core/channelz/property_list.cc b/deps/grpc/src/core/channelz/property_list.cc new file mode 100644 index 00000000000..daaa0e526c9 --- /dev/null +++ b/deps/grpc/src/core/channelz/property_list.cc @@ -0,0 +1,357 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#include "src/core/channelz/property_list.h" + +#include +#include + +#include "google/protobuf/any.upb.h" +#include "google/protobuf/empty.upb.h" +#include "src/core/util/match.h" +#include "src/proto/grpc/channelz/v2/property_list.upb.h" + +namespace grpc_core::channelz { + +namespace { +size_t GetIndex(std::vector& vec, absl::string_view value) { + auto it = std::find(vec.begin(), vec.end(), value); + if (it == vec.end()) { + vec.emplace_back(value); + return vec.size() - 1; + } else { + return it - vec.begin(); + } +} + +Json ToJson(const PropertyValue& value) { + return Match( + value, + [](absl::string_view v) { return Json::FromString(std::string(v)); }, + [](const std::string& v) { return Json::FromString(v); }, + [](int64_t v) { return Json::FromNumber(v); }, + [](uint64_t v) { return Json::FromNumber(v); }, + [](double v) { return Json::FromNumber(v); }, + [](bool v) { return Json::FromBool(v); }, + [](Duration v) { return Json::FromString(v.ToJsonString()); }, + [](Timestamp v) { + return Json::FromString( + gpr_format_timespec(v.as_timespec(GPR_CLOCK_REALTIME))); + }, + [](absl::Status v) { return Json::FromString(v.ToString()); }, + [](std::shared_ptr v) { + return Json::FromObject(v->TakeJsonObject()); + }); +} + +void FillUpbValue(const PropertyValue& value, + grpc_channelz_v2_PropertyValue* proto, upb_Arena* arena) { + Match( + value, + [proto](absl::string_view v) { + grpc_channelz_v2_PropertyValue_set_string_value( + proto, StdStringToUpbString(v)); + }, + [proto, arena](const std::string& v) { + grpc_channelz_v2_PropertyValue_set_string_value( + proto, CopyStdStringToUpbString(v, arena)); + }, + [proto](int64_t v) { + grpc_channelz_v2_PropertyValue_set_int64_value(proto, v); + }, + [proto](uint64_t v) { + grpc_channelz_v2_PropertyValue_set_uint64_value(proto, v); + }, + [proto](double v) { + grpc_channelz_v2_PropertyValue_set_double_value(proto, v); + }, + [proto](bool v) { + grpc_channelz_v2_PropertyValue_set_bool_value(proto, v); + }, + [proto, arena](Duration v) { + auto* duration_proto = + grpc_channelz_v2_PropertyValue_mutable_duration_value(proto, arena); + auto ts = v.as_timespec(); + google_protobuf_Duration_set_seconds(duration_proto, ts.tv_sec); + google_protobuf_Duration_set_nanos(duration_proto, ts.tv_nsec); + }, + [proto, arena](Timestamp v) { + auto* timestamp_proto = + grpc_channelz_v2_PropertyValue_mutable_timestamp_value(proto, + arena); + auto ts = v.as_timespec(GPR_CLOCK_REALTIME); + google_protobuf_Timestamp_set_seconds(timestamp_proto, ts.tv_sec); + google_protobuf_Timestamp_set_nanos(timestamp_proto, ts.tv_nsec); + grpc_channelz_v2_PropertyValue_set_timestamp_value(proto, + timestamp_proto); + }, + [proto, arena](absl::Status v) { + std::string text = v.ToString(); + grpc_channelz_v2_PropertyValue_set_string_value( + proto, CopyStdStringToUpbString(text, arena)); + }, + [proto, arena](std::shared_ptr v) { + auto* any = + grpc_channelz_v2_PropertyValue_mutable_any_value(proto, arena); + v->FillAny(any, arena); + }); +} + +grpc_channelz_v2_PropertyValue* ToUpbProto(const PropertyValue& value, + upb_Arena* arena) { + auto* proto = grpc_channelz_v2_PropertyValue_new(arena); + FillUpbValue(value, proto, arena); + return proto; +} +} // namespace + +void PropertyList::SetInternal(absl::string_view key, + std::optional value) { + if (value.has_value()) { + property_list_.insert_or_assign(key, *std::move(value)); + } else { + property_list_.erase(std::string(key)); + } +} + +PropertyList& PropertyList::Merge(PropertyList other) { + for (auto& [key, value] : other.property_list_) { + SetInternal(key, value); + } + return *this; +} + +Json::Object PropertyList::TakeJsonObject() { + Json::Object json; + for (auto& [key, value] : property_list_) { + json.emplace(key, ToJson(value)); + } + return json; +} + +void PropertyList::FillUpbProto(grpc_channelz_v2_PropertyList* proto, + upb_Arena* arena) { + for (auto& [key, value] : property_list_) { + grpc_channelz_v2_PropertyList_properties_set( + proto, StdStringToUpbString(key), ToUpbProto(value, arena), arena); + } +} + +void PropertyList::FillAny(google_protobuf_Any* any, upb_Arena* arena) { + auto* p = grpc_channelz_v2_PropertyList_new(arena); + FillUpbProto(p, arena); + size_t length; + auto* bytes = grpc_channelz_v2_PropertyList_serialize(p, arena, &length); + google_protobuf_Any_set_value(any, + upb_StringView_FromDataAndSize(bytes, length)); + google_protobuf_Any_set_type_url( + any, StdStringToUpbString( + "type.googleapis.com/grpc.channelz.v2.PropertyList")); +} + +Json::Object PropertyGrid::TakeJsonObject() { + Json::Object json; + Json::Array columns; + for (auto& c : columns_) { + columns.emplace_back(Json::FromString(std::string(c))); + } + json.emplace("columns", Json::FromArray(std::move(columns))); + Json::Array rows; + for (size_t r = 0; r < rows_.size(); ++r) { + Json::Object row; + row.emplace("name", Json::FromString(std::string(rows_[r]))); + Json::Array cells; + cells.reserve(columns_.size()); + for (size_t c = 0; c < columns_.size(); ++c) { + auto it = grid_.find(std::pair(c, r)); + if (it != grid_.end()) { + cells.emplace_back(ToJson(it->second)); + } else { + cells.emplace_back(Json()); + } + } + row.emplace("cells", Json::FromArray(std::move(cells))); + rows.emplace_back(Json::FromObject(std::move(row))); + } + json.emplace("rows", Json::FromArray(std::move(rows))); + return json; +} + +void PropertyGrid::FillUpbProto(grpc_channelz_v2_PropertyGrid* proto, + upb_Arena* arena) { + auto* columns_proto = grpc_channelz_v2_PropertyGrid_resize_columns( + proto, columns_.size(), arena); + for (size_t i = 0; i < columns_.size(); ++i) { + columns_proto[i] = StdStringToUpbString(columns_[i]); + } + auto* rows_proto = + grpc_channelz_v2_PropertyGrid_resize_rows(proto, rows_.size(), arena); + for (size_t r = 0; r < rows_.size(); ++r) { + auto* row_proto = grpc_channelz_v2_PropertyGrid_Row_new(arena); + rows_proto[r] = row_proto; + grpc_channelz_v2_PropertyGrid_Row_set_label(row_proto, + StdStringToUpbString(rows_[r])); + auto* row_columns_proto = grpc_channelz_v2_PropertyGrid_Row_resize_value( + row_proto, columns_.size(), arena); + for (size_t c = 0; c < columns_.size(); ++c) { + auto it = grid_.find(std::pair(c, r)); + if (it != grid_.end()) { + row_columns_proto[c] = ToUpbProto(it->second, arena); + } else { + auto* val = grpc_channelz_v2_PropertyValue_new(arena); + grpc_channelz_v2_PropertyValue_set_empty_value( + val, google_protobuf_Empty_new(arena)); + row_columns_proto[c] = val; + } + } + } +} + +void PropertyGrid::FillAny(google_protobuf_Any* any, upb_Arena* arena) { + auto* p = grpc_channelz_v2_PropertyGrid_new(arena); + FillUpbProto(p, arena); + size_t length; + auto* bytes = grpc_channelz_v2_PropertyGrid_serialize(p, arena, &length); + google_protobuf_Any_set_value(any, + upb_StringView_FromDataAndSize(bytes, length)); + google_protobuf_Any_set_type_url( + any, StdStringToUpbString( + "type.googleapis.com/grpc.channelz.v2.PropertyGrid")); +} + +void PropertyGrid::SetInternal(absl::string_view column, absl::string_view row, + std::optional value) { + int c = GetIndex(columns_, column); + int r = GetIndex(rows_, row); + if (value.has_value()) { + grid_.emplace(std::pair(c, r), *std::move(value)); + } else { + grid_.erase(std::pair(c, r)); + } +} + +PropertyGrid& PropertyGrid::SetColumn(absl::string_view column, + PropertyList values) { + int c = GetIndex(columns_, column); + std::vector keys; + for (const auto& [key, value] : values.property_list_) { + keys.push_back(key); + } + std::sort(keys.begin(), keys.end()); + for (const auto& key : keys) { + grid_.emplace(std::pair(c, GetIndex(rows_, key)), + std::move(values.property_list_.at(key))); + } + return *this; +} + +PropertyGrid& PropertyGrid::SetRow(absl::string_view row, PropertyList values) { + int r = GetIndex(rows_, row); + std::vector keys; + for (const auto& [key, value] : values.property_list_) { + keys.push_back(key); + } + std::sort(keys.begin(), keys.end()); + for (const auto& key : keys) { + grid_.emplace(std::pair(GetIndex(columns_, key), r), + std::move(values.property_list_.at(key))); + } + return *this; +} + +Json::Object PropertyTable::TakeJsonObject() { + Json::Object json; + Json::Array columns; + for (auto& c : columns_) { + columns.emplace_back(Json::FromString(std::string(c))); + } + json.emplace("columns", Json::FromArray(std::move(columns))); + Json::Array rows; + for (size_t r = 0; r < num_rows_; ++r) { + Json::Array cells; + cells.reserve(columns_.size()); + for (size_t c = 0; c < columns_.size(); ++c) { + auto it = grid_.find(std::pair(c, r)); + if (it != grid_.end()) { + cells.emplace_back(ToJson(it->second)); + } else { + cells.emplace_back(Json()); + } + } + rows.emplace_back(Json::FromArray(std::move(cells))); + } + json.emplace("rows", Json::FromArray(std::move(rows))); + return json; +} + +void PropertyTable::SetInternal(absl::string_view column, size_t row, + std::optional value) { + int c = GetIndex(columns_, column); + num_rows_ = std::max(num_rows_, row + 1); + if (value.has_value()) { + grid_.emplace(std::pair(c, row), *std::move(value)); + } else { + grid_.erase(std::pair(c, row)); + } +} + +PropertyTable& PropertyTable::SetRow(size_t row, PropertyList values) { + num_rows_ = std::max(num_rows_, row + 1); + for (auto& [key, value] : values.property_list_) { + grid_.emplace(std::pair(GetIndex(columns_, key), row), std::move(value)); + } + return *this; +} + +void PropertyTable::FillUpbProto(grpc_channelz_v2_PropertyTable* proto, + upb_Arena* arena) { + auto* columns_proto = grpc_channelz_v2_PropertyTable_resize_columns( + proto, columns_.size(), arena); + for (size_t i = 0; i < columns_.size(); ++i) { + columns_proto[i] = StdStringToUpbString(columns_[i]); + } + auto* rows_proto = + grpc_channelz_v2_PropertyTable_resize_rows(proto, num_rows_, arena); + for (size_t r = 0; r < num_rows_; ++r) { + auto* row_proto = grpc_channelz_v2_PropertyTable_Row_new(arena); + rows_proto[r] = row_proto; + auto* row_columns_proto = grpc_channelz_v2_PropertyTable_Row_resize_value( + row_proto, columns_.size(), arena); + for (size_t c = 0; c < columns_.size(); ++c) { + auto it = grid_.find({c, r}); + if (it != grid_.end()) { + row_columns_proto[c] = ToUpbProto(it->second, arena); + } else { + auto* val = grpc_channelz_v2_PropertyValue_new(arena); + grpc_channelz_v2_PropertyValue_set_empty_value( + val, google_protobuf_Empty_new(arena)); + row_columns_proto[c] = val; + } + } + } +} + +void PropertyTable::FillAny(google_protobuf_Any* any, upb_Arena* arena) { + auto* p = grpc_channelz_v2_PropertyTable_new(arena); + FillUpbProto(p, arena); + size_t length; + auto* bytes = grpc_channelz_v2_PropertyTable_serialize(p, arena, &length); + google_protobuf_Any_set_value(any, + upb_StringView_FromDataAndSize(bytes, length)); + google_protobuf_Any_set_type_url( + any, StdStringToUpbString( + "type.googleapis.com/grpc.channelz.v2.PropertyTable")); +} + +} // namespace grpc_core::channelz diff --git a/deps/grpc/src/core/channelz/property_list.h b/deps/grpc/src/core/channelz/property_list.h new file mode 100644 index 00000000000..4593065aab4 --- /dev/null +++ b/deps/grpc/src/core/channelz/property_list.h @@ -0,0 +1,202 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_PROPERTY_LIST_H +#define GRPC_SRC_CORE_CHANNELZ_PROPERTY_LIST_H + +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/any.upb.h" +#include "src/core/util/json/json.h" +#include "src/core/util/string.h" +#include "src/core/util/time.h" +#include "src/core/util/upb_utils.h" +#include "src/proto/grpc/channelz/v2/channelz.upb.h" +#include "src/proto/grpc/channelz/v2/property_list.upb.h" +#include "upb/mem/arena.h" +#include "upb/text/encode.h" + +namespace grpc_core::channelz { + +class OtherPropertyValue { + public: + virtual ~OtherPropertyValue() = default; + virtual void FillAny(google_protobuf_Any* any, upb_Arena* arena) = 0; + virtual Json::Object TakeJsonObject() = 0; +}; + +using PropertyValue = + std::variant>; + +namespace property_list_detail { + +template +struct Wrapper { + static std::optional Wrap(T value) { + return PropertyValue(std::move(value)); + } +}; + +template +struct Wrapper< + T, std::enable_if_t && std::is_unsigned_v>> { + static std::optional Wrap(T value) { + return PropertyValue(static_cast(value)); + } +}; + +template +struct Wrapper && std::is_signed_v>> { + static std::optional Wrap(T value) { + return PropertyValue(static_cast(value)); + } +}; + +template +struct Wrapper> { + static std::optional Wrap(std::optional value) { + if (value.has_value()) return Wrapper::Wrap(*std::move(value)); + return std::nullopt; + } +}; + +template <> +struct Wrapper { + static std::optional Wrap(const char* value) { + if (value == nullptr) return std::nullopt; + return absl::string_view(value); + } +}; + +template <> +struct Wrapper> { + static std::optional Wrap( + std::shared_ptr value) { + if (value == nullptr) return std::nullopt; + return PropertyValue(std::move(value)); + } +}; + +template +struct Wrapper && + std::is_final_v>> { + static std::optional Wrap(T value) { + return PropertyValue(std::make_shared(std::move(value))); + } +}; + +template <> +struct Wrapper { + static std::optional Wrap(bool value) { + return PropertyValue(value); + } +}; + +} // namespace property_list_detail + +// PropertyList contains a bag of key->value (for mostly arbitrary value +// types) for reporting out state from channelz - the big idea is that you +// should be able to call `PropertyList().Set("a", this->a)` and generate +// something that channelz presenters can interpret. It's currently defined in +// terms of JSON, but as we adopt channelz-v2 it's expected we'll change this +// to capture protobuf directly. +class PropertyList final : public OtherPropertyValue { + public: + template + PropertyList& Set(absl::string_view key, T value) { + SetInternal(key, property_list_detail::Wrapper::Wrap(value)); + return *this; + } + + PropertyList& Merge(PropertyList other); + + // TODO(ctiller): remove soon, switch to just FillUpbProto. + Json::Object TakeJsonObject() override; + void FillUpbProto(grpc_channelz_v2_PropertyList* proto, upb_Arena* arena); + void FillAny(google_protobuf_Any* any, upb_Arena* arena) override; + + private: + void SetInternal(absl::string_view key, std::optional value); + + friend class PropertyGrid; + friend class PropertyTable; + + absl::flat_hash_map property_list_; +}; + +// PropertyGrid is much the same as PropertyList, but it is two dimensional. +// Each row and column can be set independently. +// Rows and columns are ordered by the first setting of a value on them. +class PropertyGrid final : public OtherPropertyValue { + public: + template + PropertyGrid& Set(absl::string_view column, absl::string_view row, T value) { + SetInternal(column, row, property_list_detail::Wrapper::Wrap(value)); + return *this; + } + + PropertyGrid& SetColumn(absl::string_view column, PropertyList values); + PropertyGrid& SetRow(absl::string_view row, PropertyList values); + + Json::Object TakeJsonObject() override; + void FillUpbProto(grpc_channelz_v2_PropertyGrid* proto, upb_Arena* arena); + void FillAny(google_protobuf_Any* any, upb_Arena* arena) override; + + private: + void SetInternal(absl::string_view column, absl::string_view row, + std::optional value); + + std::vector columns_; + std::vector rows_; + absl::flat_hash_map, PropertyValue> grid_; +}; + +// PropertyTable is much the same as PropertyGrid, but has numbered rows +// instead of named rows. +class PropertyTable final : public OtherPropertyValue { + public: + template + PropertyTable& Set(absl::string_view column, size_t row, T value) { + SetInternal(column, row, property_list_detail::Wrapper::Wrap(value)); + return *this; + } + + PropertyTable& SetRow(size_t row, PropertyList values); + PropertyTable& AppendRow(PropertyList values) { + return SetRow(num_rows_, std::move(values)); + } + + Json::Object TakeJsonObject() override; + void FillUpbProto(grpc_channelz_v2_PropertyTable* proto, upb_Arena* arena); + void FillAny(google_protobuf_Any* any, upb_Arena* arena) override; + + private: + void SetInternal(absl::string_view column, size_t row, + std::optional value); + + std::vector columns_; + size_t num_rows_ = 0; + absl::flat_hash_map, PropertyValue> grid_; +}; + +} // namespace grpc_core::channelz + +#endif // GRPC_SRC_CORE_CHANNELZ_PROPERTY_LIST_H diff --git a/deps/grpc/src/core/channelz/ztrace_collector.h b/deps/grpc/src/core/channelz/ztrace_collector.h index 5489d33c014..80cd5bbcd1d 100644 --- a/deps/grpc/src/core/channelz/ztrace_collector.h +++ b/deps/grpc/src/core/channelz/ztrace_collector.h @@ -25,6 +25,7 @@ #include "src/core/channelz/channelz.h" #include "src/core/lib/debug/trace.h" #include "src/core/util/json/json_writer.h" +#include "src/core/util/memory_usage.h" #include "src/core/util/single_set_ptr.h" #include "src/core/util/string.h" #include "src/core/util/sync.h" @@ -168,7 +169,7 @@ class ZTraceCollector { }; template void Append(std::pair value) { - memory_used_ += value.second.MemoryUsage(); + memory_used_ += MemoryUsageOf(value.second); while (memory_used_ > memory_cap_) RemoveMostRecent(); std::get >(data).push_back(std::move(value)); } @@ -187,7 +188,7 @@ class ZTraceCollector { collection.front().first < state->most_recent) { state->enact = +[](Instance* instance) { auto& collection = std::get >(instance->data); - const size_t ent_usage = collection.front().second.MemoryUsage(); + const size_t ent_usage = MemoryUsageOf(collection.front().second); CHECK_GE(instance->memory_used_, ent_usage); instance->memory_used_ -= ent_usage; collection.pop_front(); diff --git a/deps/grpc/src/core/channelz/zviz/data.cc b/deps/grpc/src/core/channelz/zviz/data.cc new file mode 100644 index 00000000000..d4d1074b8ef --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/data.cc @@ -0,0 +1,139 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/channelz/zviz/data.h" + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "absl/types/span.h" +#include "src/core/channelz/zviz/environment.h" +#include "src/core/channelz/zviz/layout.h" +#include "src/core/util/no_destruct.h" +#include "src/proto/grpc/channelz/v2/channelz.pb.h" +#include "src/proto/grpc/channelz/v2/property_list.pb.h" + +namespace grpc_zviz { + +namespace { + +void Format(Environment& env, const grpc::channelz::v2::PropertyValue& value, + layout::Element& element) { + switch (value.kind_case()) { + case grpc::channelz::v2::PropertyValue::KIND_NOT_SET: + case grpc::channelz::v2::PropertyValue::kEmptyValue: + break; + case grpc::channelz::v2::PropertyValue::kAnyValue: + Format(env, value.any_value(), element); + break; + case grpc::channelz::v2::PropertyValue::kStringValue: + element.AppendText(layout::Intent::kValue, value.string_value()); + break; + case grpc::channelz::v2::PropertyValue::kInt64Value: + element.AppendText(layout::Intent::kValue, + absl::StrCat(value.int64_value())); + break; + case grpc::channelz::v2::PropertyValue::kUint64Value: + element.AppendText(layout::Intent::kValue, + absl::StrCat(value.uint64_value())); + break; + case grpc::channelz::v2::PropertyValue::kDoubleValue: + element.AppendText(layout::Intent::kValue, + absl::StrCat(value.double_value())); + break; + case grpc::channelz::v2::PropertyValue::kBoolValue: + element.AppendText(layout::Intent::kValue, + value.bool_value() ? "true" : "false"); + break; + case grpc::channelz::v2::PropertyValue::kTimestampValue: + element.AppendTimestamp(value.timestamp_value()); + break; + case grpc::channelz::v2::PropertyValue::kDurationValue: + element.AppendDuration(value.duration_value()); + break; + } +} + +bool PropertyListFormatter(Environment& env, google::protobuf::Any value, + layout::Element& element) { + grpc::channelz::v2::PropertyList property_list; + if (!value.UnpackTo(&property_list)) return false; + auto& table = element.AppendTable(layout::TableIntent::kPropertyList); + for (const auto& [key, value] : property_list.properties()) { + table.AppendColumn().AppendText(layout::Intent::kKey, key); + Format(env, value, table.AppendColumn()); + table.NewRow(); + } + return true; +} + +bool PropertyGridFormatter(Environment& env, google::protobuf::Any value, + layout::Element& element) { + grpc::channelz::v2::PropertyGrid property_grid; + if (!value.UnpackTo(&property_grid)) return false; + auto& table = element.AppendTable(layout::TableIntent::kPropertyGrid); + table.AppendColumn(); + for (const auto& column : property_grid.columns()) { + table.AppendColumn().AppendText(layout::Intent::kKey, column); + } + for (const auto& row : property_grid.rows()) { + table.NewRow(); + table.AppendColumn().AppendText(layout::Intent::kKey, row.label()); + for (const auto& value : row.value()) { + Format(env, value, table.AppendColumn()); + } + } + return true; +} + +using Formatter = bool (*)(Environment&, google::protobuf::Any, + layout::Element&); + +const grpc_core::NoDestruct> + kDataFormatters([]() { + absl::flat_hash_map formatters; + formatters.emplace("type.googleapis.com/grpc.channelz.v2.PropertyList", + PropertyListFormatter); + formatters.emplace("type.googleapis.com/grpc.channelz.v2.PropertyGrid", + PropertyGridFormatter); + return formatters; + }()); + +void Failed(absl::string_view message, const google::protobuf::Any& value, + layout::Element& element) { + element.AppendText(layout::Intent::kNote, message); + element.AppendText(layout::Intent::kData, value.DebugString()); +} + +} // namespace + +void Format(Environment& env, const google::protobuf::Any& value, + layout::Element& element) { + auto formatter = kDataFormatters->find(value.type_url()); + if (formatter != kDataFormatters->end()) { + if (!formatter->second(env, value, element)) { + Failed("Failed to format type", value, element); + } + } else { + Failed("Unknown type", value, element); + } +} + +void Format(Environment& env, const grpc::channelz::v2::Data& data, + layout::Element& element) { + Format(env, data.value(), + element.AppendData(data.name(), data.value().type_url())); +} + +} // namespace grpc_zviz diff --git a/deps/grpc/src/core/channelz/zviz/data.h b/deps/grpc/src/core/channelz/zviz/data.h new file mode 100644 index 00000000000..6b0caf07341 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/data.h @@ -0,0 +1,34 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_DATA_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_DATA_H + +#include + +#include "src/core/channelz/zviz/environment.h" +#include "src/core/channelz/zviz/layout.h" +#include "src/proto/grpc/channelz/v2/channelz.pb.h" + +namespace grpc_zviz { + +void Format(Environment& env, const grpc::channelz::v2::Data& data, + layout::Element& element); + +void Format(Environment& env, const google::protobuf::Any& value, + layout::Element& element); + +} // namespace grpc_zviz + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_DATA_H diff --git a/deps/grpc/src/core/channelz/zviz/entity.cc b/deps/grpc/src/core/channelz/zviz/entity.cc new file mode 100644 index 00000000000..6bdae906c27 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/entity.cc @@ -0,0 +1,51 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/channelz/zviz/entity.h" + +#include "absl/strings/str_cat.h" +#include "src/core/channelz/zviz/data.h" +#include "src/core/channelz/zviz/strings.h" +#include "src/core/channelz/zviz/trace.h" + +namespace grpc_zviz { + +void Format(Environment& env, const grpc::channelz::v2::Entity& entity, + layout::Element& element) { + element.AppendText( + layout::Intent::kBanner, + absl::StrCat(entity.orphaned() ? "Orphaned " : "", + DisplayKind(entity.kind()), " ", entity.id())); + if (entity.parents_size() > 0) { + auto& grp = element.AppendGroup(layout::Intent::kHeading); + grp.AppendText(layout::Intent::kHeading, "Parents:"); + for (int64_t parent_id : entity.parents()) { + grp.AppendEntityLink(env, parent_id); + } + } + if (entity.trace_size() > 0) { + auto& grp = element.AppendGroup(layout::Intent::kTrace); + grp.AppendText(layout::Intent::kHeading, "Trace:"); + auto& table = grp.AppendTable(layout::TableIntent::kTrace); + for (const auto& trace : entity.trace()) { + Format(env, trace, table); + table.NewRow(); + } + } + for (const auto& data : entity.data()) { + Format(env, data, element); + } +} + +} // namespace grpc_zviz diff --git a/deps/grpc/src/core/channelz/zviz/entity.h b/deps/grpc/src/core/channelz/zviz/entity.h new file mode 100644 index 00000000000..0ad57a2c5ec --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/entity.h @@ -0,0 +1,29 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_ENTITY_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_ENTITY_H + +#include "src/core/channelz/zviz/environment.h" +#include "src/core/channelz/zviz/layout.h" +#include "src/proto/grpc/channelz/v2/channelz.pb.h" + +namespace grpc_zviz { + +void Format(Environment& env, const grpc::channelz::v2::Entity& entity, + layout::Element& element); + +} // namespace grpc_zviz + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_ENTITY_H diff --git a/deps/grpc/src/core/channelz/zviz/environment.cc b/deps/grpc/src/core/channelz/zviz/environment.cc new file mode 100644 index 00000000000..1d1ffb79bbc --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/environment.cc @@ -0,0 +1,32 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/channelz/zviz/environment.h" + +#include "src/core/channelz/zviz/strings.h" + +namespace grpc_zviz { + +std::string Environment::EntityLinkText(int64_t entity_id) { + auto entity = GetEntity(entity_id); + std::string kind; + if (!entity.ok()) { + kind = "Entity"; + } else { + kind = DisplayKind(entity->kind()); + } + return absl::StrCat(kind, " ", entity_id); +} + +} // namespace grpc_zviz diff --git a/deps/grpc/src/core/channelz/zviz/environment.h b/deps/grpc/src/core/channelz/zviz/environment.h new file mode 100644 index 00000000000..9b745f82afb --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/environment.h @@ -0,0 +1,36 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_ENVIRONMENT_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_ENVIRONMENT_H + +#include + +#include "absl/status/statusor.h" +#include "src/proto/grpc/channelz/v2/channelz.pb.h" + +namespace grpc_zviz { + +class Environment { + public: + virtual ~Environment() = default; + virtual std::string EntityLinkTarget(int64_t entity_id) = 0; + virtual std::string EntityLinkText(int64_t entity_id); + virtual absl::StatusOr GetEntity( + int64_t entity_id) = 0; +}; + +} // namespace grpc_zviz + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_ENVIRONMENT_H diff --git a/deps/grpc/src/core/channelz/zviz/html.cc b/deps/grpc/src/core/channelz/zviz/html.cc new file mode 100644 index 00000000000..c6db99c8dca --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/html.cc @@ -0,0 +1,105 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/channelz/zviz/html.h" + +#include "absl/functional/function_ref.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/string_view.h" + +namespace grpc_zviz::html { + +std::string HtmlEscape(absl::string_view text) { + return absl::StrReplaceAll(text, {{"&", "&"}, + {"<", "<"}, + {">", ">"}, + {"\"", """}, + {"'", "'"}}); +} + +Container Div(std::string clazz, absl::FunctionRef f) { + Container div("div"); + div.Attribute("class", std::move(clazz)); + f(div); + return div; +} + +std::string Container::Render() const { + std::string s = absl::StrCat("<", tag_); + for (const auto& [name, value] : attributes_) { + absl::StrAppend(&s, " ", name, "=\"", HtmlEscape(value), "\""); + } + if (items_.empty()) { + absl::StrAppend(&s, "/>"); + return s; + } + absl::StrAppend(&s, ">"); + for (const auto& item : items_) { + absl::StrAppend(&s, item->Render()); + } + absl::StrAppend(&s, ""); + return s; +} + +Container& Container::Link(std::string text, std::string url) { + NewItem("a") + .Attribute("href", std::move(url)) + .Text(std::move(text)); + return *this; +} + +Container& Container::Div(std::string clazz, + absl::FunctionRef f) { + return NewItem(html::Div(std::move(clazz), f)); +} + +Container& Container::NewDiv(std::string clazz) { + auto& div = NewItem("div"); + div.Attribute("class", std::move(clazz)); + return div; +} + +Table& Container::NewTable() { return NewItem(); } + +Container& Table::Cell(int column, int row) { + num_columns_ = std::max(num_columns_, column + 1); + num_rows_ = std::max(num_rows_, row + 1); + auto it = cells_.find(std::tuple(column, row)); + if (it == cells_.end()) { + it = cells_.emplace(std::tuple(column, row), Container("td")).first; + } + return it->second; +} + +std::string Table::Render() const { + if (cells_.empty()) return "
"; + std::string s = "
"; + for (int r = 0; r < num_rows_; ++r) { + absl::StrAppend(&s, ""); + for (int c = 0; c < num_columns_; ++c) { + auto it = cells_.find(std::tuple(c, r)); + if (it == cells_.end()) { + absl::StrAppend(&s, ""); + } + absl::StrAppend(&s, "
"); + } else { + absl::StrAppend(&s, it->second.Render()); + } + } + absl::StrAppend(&s, "
"); + return s; +} + +} // namespace grpc_zviz::html diff --git a/deps/grpc/src/core/channelz/zviz/html.h b/deps/grpc/src/core/channelz/zviz/html.h new file mode 100644 index 00000000000..92c9cb20e29 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/html.h @@ -0,0 +1,103 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_HTML_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_HTML_H + +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/functional/function_ref.h" +#include "absl/strings/string_view.h" + +namespace grpc_zviz::html { + +std::string HtmlEscape(absl::string_view text); + +class Item { + public: + virtual std::string Render() const = 0; + virtual ~Item() = default; +}; + +class Text final : public Item { + public: + explicit Text(std::string text) : text_(std::move(text)) {} + std::string Render() const override { return HtmlEscape(text_); } + + private: + std::string text_; +}; + +class Table; + +class Container final : public Item { + public: + explicit Container(std::string tag) : tag_(std::move(tag)) {} + std::string Render() const override; + + Container& Attribute(std::string name, std::string value) { + attributes_.emplace_back(std::move(name), std::move(value)); + return *this; + } + + template + T& NewItem(Args&&... args) { + auto p = std::make_unique(std::forward(args)...); + auto* pp = p.get(); + items_.push_back(std::move(p)); + return *pp; + } + + Container& Text(std::string text) { + NewItem(std::move(text)); + return *this; + } + Container& Link(std::string text, std::string url); + Container& Div(std::string clazz, absl::FunctionRef f); + Container& NewDiv(std::string clazz); + Container& TextDiv(std::string clazz, std::string text) { + return Div(clazz, [&](Container& div) { div.Text(std::move(text)); }); + } + Container& LinkDiv(std::string clazz, std::string text, std::string url) { + return Div(clazz, [&](Container& div) { div.Link(std::move(text), url); }); + } + Table& NewTable(); + + private: + std::string tag_; + std::vector> attributes_; + std::vector> items_; +}; + +Container Div(std::string clazz, absl::FunctionRef f); + +class Table final : public Item { + public: + Container& Cell(int column, int row); + std::string Render() const override; + + private: + using Address = std::tuple; + int num_columns_ = 0; + int num_rows_ = 0; + absl::flat_hash_map cells_; +}; + +} // namespace grpc_zviz::html + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_HTML_H diff --git a/deps/grpc/src/core/channelz/zviz/layout.cc b/deps/grpc/src/core/channelz/zviz/layout.cc new file mode 100644 index 00000000000..1bb525dd773 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/layout.cc @@ -0,0 +1,37 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/channelz/zviz/layout.h" + +namespace grpc_zviz::layout { + +Element& Element::AppendTimestamp(google::protobuf::Timestamp timestamp) { + return AppendText( + Intent::kTimestamp, + absl::FormatTime(absl::FromUnixSeconds(timestamp.seconds()) + + absl::Nanoseconds(timestamp.nanos()))); +} + +Element& Element::AppendDuration(google::protobuf::Duration duration) { + return AppendText(Intent::kDuration, + absl::FormatDuration(absl::Seconds(duration.seconds()) + + absl::Nanoseconds(duration.nanos()))); +} + +Element& Element::AppendEntityLink(Environment& env, int64_t entity_id) { + return AppendLink(Intent::kEntityRef, env.EntityLinkText(entity_id), + env.EntityLinkTarget(entity_id)); +} + +} // namespace grpc_zviz::layout diff --git a/deps/grpc/src/core/channelz/zviz/layout.h b/deps/grpc/src/core/channelz/zviz/layout.h new file mode 100644 index 00000000000..f932bd34738 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/layout.h @@ -0,0 +1,130 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_LAYOUT_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_LAYOUT_H + +#include + +#include "google/protobuf/duration.pb.h" +#include "google/protobuf/timestamp.pb.h" +#include "src/core/channelz/zviz/environment.h" + +namespace grpc_zviz::layout { + +enum class Intent { + kBanner, + kHeading, + kEntityRef, + kTrace, + kTraceDescription, + kData, + kTimestamp, + kDuration, + kNote, + kKey, + kValue, +}; + +template +void AbslStringify(Sink& sink, Intent intent) { + switch (intent) { + case Intent::kBanner: + sink.Append("banner"); + break; + case Intent::kHeading: + sink.Append("heading"); + break; + case Intent::kEntityRef: + sink.Append("entity_ref"); + break; + case Intent::kTrace: + sink.Append("trace"); + break; + case Intent::kTraceDescription: + sink.Append("trace_description"); + break; + case Intent::kTimestamp: + sink.Append("timestamp"); + break; + case Intent::kDuration: + sink.Append("duration"); + break; + case Intent::kNote: + sink.Append("note"); + break; + case Intent::kData: + sink.Append("data"); + break; + case Intent::kKey: + sink.Append("key"); + break; + case Intent::kValue: + sink.Append("value"); + break; + } +} + +enum class TableIntent { + kTrace, + kPropertyList, + kPropertyGrid, +}; + +template +void AbslStringify(Sink& sink, TableIntent intent) { + switch (intent) { + case TableIntent::kTrace: + sink.Append("trace"); + break; + case TableIntent::kPropertyList: + sink.Append("property_list"); + break; + case TableIntent::kPropertyGrid: + sink.Append("property_grid"); + break; + } +} + +class Table; + +class Element { + public: + virtual ~Element() = default; + + // Append an element and return *this. + virtual Element& AppendText(Intent intent, absl::string_view text) = 0; + virtual Element& AppendLink(Intent intent, absl::string_view text, + absl::string_view href) = 0; + // Helpers to append common intents. + Element& AppendTimestamp(google::protobuf::Timestamp timestamp); + Element& AppendDuration(google::protobuf::Duration duration); + Element& AppendEntityLink(Environment& env, int64_t entity_id); + // These create new groups and return a reference to the new group. + virtual Element& AppendGroup(Intent intent) = 0; + virtual Element& AppendData(absl::string_view name, + absl::string_view type) = 0; + virtual Table& AppendTable(TableIntent intent) = 0; +}; + +class Table { + public: + virtual ~Table() = default; + virtual Element& AppendColumn() = 0; + virtual void NewRow() = 0; +}; + +} // namespace grpc_zviz::layout + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_LAYOUT_H diff --git a/deps/grpc/src/core/channelz/zviz/layout_html.cc b/deps/grpc/src/core/channelz/zviz/layout_html.cc new file mode 100644 index 00000000000..43cbccaf116 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/layout_html.cc @@ -0,0 +1,82 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#include "src/core/channelz/zviz/layout_html.h" + +namespace grpc_zviz::layout { + +namespace { + +std::string IntentToStyle(Intent intent) { + switch (intent) { + case Intent::kBanner: + return "zviz-banner"; + case Intent::kHeading: + return "zviz-heading"; + case Intent::kEntityRef: + return "zviz-entity-ref"; + case Intent::kTrace: + return "zviz-trace"; + case Intent::kTraceDescription: + return "zviz-trace-description"; + case Intent::kData: + return "zviz-data"; + case Intent::kTimestamp: + return "zviz-timestamp"; + case Intent::kNote: + return "zviz-note"; + case Intent::kKey: + return "zviz-key"; + case Intent::kValue: + return "zviz-value"; + case Intent::kDuration: + return "zviz-duration"; + } +} + +} // namespace + +Element& HtmlElement::AppendText(Intent intent, absl::string_view text) { + container_.TextDiv(IntentToStyle(intent), std::string(text)); + return *this; +} + +Element& HtmlElement::AppendLink(Intent intent, absl::string_view text, + absl::string_view href) { + container_.LinkDiv(IntentToStyle(intent), std::string(text), + std::string(href)); + return *this; +} + +Element& HtmlElement::AppendGroup(Intent intent) { + return *children_.emplace_back( + std::make_unique(container_.NewDiv(IntentToStyle(intent)))); +} + +Element& HtmlElement::AppendData(absl::string_view name, absl::string_view) { + auto& grp = AppendGroup(Intent::kData); + grp.AppendText(Intent::kHeading, name); + return grp; +} + +Table& HtmlElement::AppendTable(TableIntent) { + return *tables_.emplace_back( + std::make_unique(container_.NewTable())); +} + +Element& HtmlTable::AppendColumn() { + return *elements_.emplace_back( + std::make_unique(table_.Cell(column_++, row_))); +} +} // namespace grpc_zviz::layout diff --git a/deps/grpc/src/core/channelz/zviz/layout_html.h b/deps/grpc/src/core/channelz/zviz/layout_html.h new file mode 100644 index 00000000000..03151a68b74 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/layout_html.h @@ -0,0 +1,61 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_LAYOUT_HTML_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_LAYOUT_HTML_H + +#include "src/core/channelz/zviz/environment.h" +#include "src/core/channelz/zviz/html.h" +#include "src/core/channelz/zviz/layout.h" + +namespace grpc_zviz::layout { + +class HtmlTable; + +class HtmlElement final : public Element { + public: + explicit HtmlElement(html::Container& container) : container_(container) {} + Element& AppendText(Intent intent, absl::string_view text) override; + Element& AppendLink(Intent intent, absl::string_view text, + absl::string_view href) override; + Element& AppendGroup(Intent intent) override; + Element& AppendData(absl::string_view name, absl::string_view type) override; + Table& AppendTable(TableIntent intent) override; + + private: + html::Container& container_; + std::vector> children_; + std::vector> tables_; +}; + +class HtmlTable final : public Table { + public: + explicit HtmlTable(html::Table& table) : table_(table) {} + Element& AppendColumn() override; + + void NewRow() override { + column_ = 0; + ++row_; + } + + private: + html::Table& table_; + std::vector> elements_; + int column_ = 0; + int row_ = 0; +}; + +} // namespace grpc_zviz::layout + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_LAYOUT_HTML_H diff --git a/deps/grpc/src/core/channelz/zviz/strings.cc b/deps/grpc/src/core/channelz/zviz/strings.cc new file mode 100644 index 00000000000..0a82007f5e4 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/strings.cc @@ -0,0 +1,29 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/channelz/zviz/strings.h" + +#include "absl/strings/str_cat.h" + +namespace grpc_zviz { + +std::string DisplayKind(absl::string_view kind) { + if (kind.empty()) return "Entity"; + if (kind == "channel") return "Channel"; + if (kind == "subchannel") return "Subchannel"; + if (kind == "socket") return "Socket"; + return absl::StrCat("Entity kind '", kind, "'"); +} + +} // namespace grpc_zviz diff --git a/deps/grpc/src/core/channelz/zviz/strings.h b/deps/grpc/src/core/channelz/zviz/strings.h new file mode 100644 index 00000000000..dd524f932c5 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/strings.h @@ -0,0 +1,28 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_STRINGS_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_STRINGS_H + +#include + +#include "absl/strings/string_view.h" + +namespace grpc_zviz { + +std::string DisplayKind(absl::string_view kind); + +} // namespace grpc_zviz + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_STRINGS_H diff --git a/deps/grpc/src/core/channelz/zviz/trace.cc b/deps/grpc/src/core/channelz/zviz/trace.cc new file mode 100644 index 00000000000..4e5ab212a28 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/trace.cc @@ -0,0 +1,36 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/channelz/zviz/trace.h" + +#include "src/core/channelz/zviz/data.h" + +namespace grpc_zviz { + +void Format(Environment& env, const grpc::channelz::v2::TraceEvent& trace_event, + layout::Table& trace_table) { + trace_table.AppendColumn().AppendTimestamp(trace_event.timestamp()); + auto& event = trace_table.AppendColumn(); + if (!trace_event.description().empty()) { + event.AppendText(layout::Intent::kTraceDescription, + trace_event.description()); + } + if (trace_event.data_size() > 0) { + for (const auto& data : trace_event.data()) { + Format(env, data, event); + } + } +} + +} // namespace grpc_zviz diff --git a/deps/grpc/src/core/channelz/zviz/trace.h b/deps/grpc/src/core/channelz/zviz/trace.h new file mode 100644 index 00000000000..3f815524b32 --- /dev/null +++ b/deps/grpc/src/core/channelz/zviz/trace.h @@ -0,0 +1,31 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_CHANNELZ_ZVIZ_TRACE_H +#define GRPC_SRC_CORE_CHANNELZ_ZVIZ_TRACE_H + +#include + +#include "src/core/channelz/zviz/environment.h" +#include "src/core/channelz/zviz/layout.h" +#include "src/proto/grpc/channelz/v2/channelz.pb.h" + +namespace grpc_zviz { + +void Format(Environment& env, const grpc::channelz::v2::TraceEvent& trace_event, + layout::Table& trace_table); + +} // namespace grpc_zviz + +#endif // GRPC_SRC_CORE_CHANNELZ_ZVIZ_TRACE_H diff --git a/deps/grpc/src/core/client_channel/client_channel.cc b/deps/grpc/src/core/client_channel/client_channel.cc index 1681bb7a9a2..fb42488eb1d 100644 --- a/deps/grpc/src/core/client_channel/client_channel.cc +++ b/deps/grpc/src/core/client_channel/client_channel.cc @@ -495,24 +495,13 @@ class ClientChannel::ClientChannelControlHelper return *client_channel_->stats_plugin_group_; } - void AddTraceEvent(TraceSeverity severity, absl::string_view message) override + void AddTraceEvent(absl::string_view message) override ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { if (client_channel_->resolver_ == nullptr) return; // Shutting down. - if (client_channel_->channelz_node_ != nullptr) { - client_channel_->channelz_node_->AddTraceEvent( - ConvertSeverityEnum(severity), - grpc_slice_from_copied_buffer(message.data(), message.size())); - } + GRPC_CHANNELZ_LOG(client_channel_->channelz_node_) << std::string(message); } private: - static channelz::ChannelTrace::Severity ConvertSeverityEnum( - TraceSeverity severity) { - if (severity == TRACE_INFO) return channelz::ChannelTrace::Info; - if (severity == TRACE_WARNING) return channelz::ChannelTrace::Warning; - return channelz::ChannelTrace::Error; - } - WeakRefCountedPtr client_channel_; }; @@ -1158,12 +1147,8 @@ void ClientChannel::OnResolverResultChangedLocked(Resolver::Result result) { } // Add channel trace event. if (!trace_strings.empty()) { - std::string message = - absl::StrCat("Resolution event: ", absl::StrJoin(trace_strings, ", ")); - if (channelz_node_ != nullptr) { - channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_from_cpp_string(message)); - } + GRPC_CHANNELZ_LOG(channelz_node_) + << "Resolution event: " << absl::StrJoin(trace_strings, ", "); } } @@ -1279,8 +1264,7 @@ void ClientChannel::UpdateServiceConfigInDataPlaneLocked( ChannelArgs new_args = args.SetObject(this).SetObject(saved_service_config_); // Construct filter stack. auto new_blackboard = MakeRefCounted(); - InterceptionChainBuilder builder(new_args, blackboard_.get(), - new_blackboard.get()); + InterceptionChainBuilder builder(new_args, new_blackboard.get()); if (idle_timeout_ != Duration::Zero()) { builder.AddOnServerTrailingMetadata([this](ServerMetadata&) { if (idle_state_.DecreaseCallCount()) StartIdleTimer(); @@ -1289,16 +1273,18 @@ void ClientChannel::UpdateServiceConfigInDataPlaneLocked( CoreConfiguration::Get().channel_init().AddToInterceptionChainBuilder( GRPC_CLIENT_CHANNEL, builder); // Add filters returned by the config selector (e.g., xDS HTTP filters). - config_selector->AddFilters(builder); + config_selector->AddFilters(builder, blackboard_.get(), new_blackboard.get()); const bool enable_retries = !channel_args_.WantMinimalStack() && channel_args_.GetBool(GRPC_ARG_ENABLE_RETRIES).value_or(true); if (enable_retries) { + RetryInterceptor::UpdateBlackboard(*saved_service_config_, + blackboard_.get(), new_blackboard.get()); builder.Add(); } + blackboard_ = std::move(new_blackboard); // Create call destination. auto top_of_stack_call_destination = builder.Build(call_destination_); - blackboard_ = std::move(new_blackboard); // Send result to data plane. if (!top_of_stack_call_destination.ok()) { resolver_data_for_calls_.Set(MaybeRewriteIllegalStatusCode( @@ -1319,13 +1305,16 @@ void ClientChannel::UpdateStateLocked(grpc_connectivity_state state, state_tracker_.SetState(state, status, reason); if (channelz_node_ != nullptr) { channelz_node_->SetConnectivityState(state); - std::string trace = - channelz::ChannelNode::GetChannelConnectivityStateChangeString(state); if (!status.ok() || state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - absl::StrAppend(&trace, " status:", status.ToString()); + GRPC_CHANNELZ_LOG(channelz_node_) + << channelz::ChannelNode::GetChannelConnectivityStateChangeString( + state) + << " status: " << status; + } else { + GRPC_CHANNELZ_LOG(channelz_node_) + << channelz::ChannelNode::GetChannelConnectivityStateChangeString( + state); } - channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_from_cpp_string(std::move(trace))); } } diff --git a/deps/grpc/src/core/client_channel/client_channel_filter.cc b/deps/grpc/src/core/client_channel/client_channel_filter.cc index 6b5fbef15f6..3a3490e6839 100644 --- a/deps/grpc/src/core/client_channel/client_channel_filter.cc +++ b/deps/grpc/src/core/client_channel/client_channel_filter.cc @@ -980,24 +980,13 @@ class ClientChannelFilter::ClientChannelControlHelper final return **chand_->owning_stack_->stats_plugin_group; } - void AddTraceEvent(TraceSeverity severity, absl::string_view message) override + void AddTraceEvent(absl::string_view message) override ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) { if (chand_->resolver_ == nullptr) return; // Shutting down. - if (chand_->channelz_node_ != nullptr) { - chand_->channelz_node_->AddTraceEvent( - ConvertSeverityEnum(severity), - grpc_slice_from_copied_buffer(message.data(), message.size())); - } + GRPC_CHANNELZ_LOG(chand_->channelz_node_) << std::string(message); } private: - static channelz::ChannelTrace::Severity ConvertSeverityEnum( - TraceSeverity severity) { - if (severity == TRACE_INFO) return channelz::ChannelTrace::Info; - if (severity == TRACE_WARNING) return channelz::ChannelTrace::Warning; - return channelz::ChannelTrace::Error; - } - ClientChannelFilter* chand_; }; @@ -1333,12 +1322,8 @@ void ClientChannelFilter::OnResolverResultChangedLocked( } // Add channel trace event. if (!trace_strings.empty()) { - std::string message = - absl::StrCat("Resolution event: ", absl::StrJoin(trace_strings, ", ")); - if (channelz_node_ != nullptr) { - channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_from_cpp_string(message)); - } + GRPC_CHANNELZ_LOG(channelz_node_) + << "Resolution event: " << absl::StrJoin(trace_strings, ", "); } } @@ -1460,18 +1445,20 @@ void ClientChannelFilter::UpdateServiceConfigInDataPlaneLocked( !new_args.WantMinimalStack() && new_args.GetBool(GRPC_ARG_ENABLE_RETRIES).value_or(true); // Construct dynamic filter stack. + auto new_blackboard = MakeRefCounted(); std::vector filters = - config_selector->GetFilters(); + config_selector->GetFilters(blackboard_.get(), new_blackboard.get()); if (enable_retries) { + RetryFilter::UpdateBlackboard(*service_config, blackboard_.get(), + new_blackboard.get()); filters.push_back(&RetryFilter::kVtable); } else { filters.push_back(&DynamicTerminationFilter::kFilterVtable); } - auto new_blackboard = MakeRefCounted(); - RefCountedPtr dynamic_filters = DynamicFilters::Create( - new_args, std::move(filters), blackboard_.get(), new_blackboard.get()); - CHECK(dynamic_filters != nullptr); blackboard_ = std::move(new_blackboard); + RefCountedPtr dynamic_filters = + DynamicFilters::Create(new_args, std::move(filters), blackboard_.get()); + CHECK(dynamic_filters != nullptr); // Grab data plane lock to update service config. // // We defer unreffing the old values (and deallocating memory) until @@ -1552,13 +1539,16 @@ void ClientChannelFilter::UpdateStateLocked(grpc_connectivity_state state, state_tracker_.SetState(state, status, reason); if (channelz_node_ != nullptr) { channelz_node_->SetConnectivityState(state); - std::string trace = - channelz::ChannelNode::GetChannelConnectivityStateChangeString(state); if (!status.ok() || state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - absl::StrAppend(&trace, " status:", status.ToString()); + GRPC_CHANNELZ_LOG(channelz_node_) + << channelz::ChannelNode::GetChannelConnectivityStateChangeString( + state); + } else { + GRPC_CHANNELZ_LOG(channelz_node_) + << channelz::ChannelNode::GetChannelConnectivityStateChangeString( + state) + << " status: " << status.ToString(); } - channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_from_cpp_string(std::move(trace))); } } diff --git a/deps/grpc/src/core/client_channel/config_selector.h b/deps/grpc/src/core/client_channel/config_selector.h index 3aab7e83c06..359f85340af 100644 --- a/deps/grpc/src/core/client_channel/config_selector.h +++ b/deps/grpc/src/core/client_channel/config_selector.h @@ -30,6 +30,7 @@ #include "src/core/call/interception_chain.h" #include "src/core/call/metadata_batch.h" #include "src/core/client_channel/client_channel_internal.h" +#include "src/core/filter/blackboard.h" #include "src/core/lib/channel/channel_fwd.h" #include "src/core/lib/resource_quota/arena.h" #include "src/core/lib/slice/slice.h" @@ -61,9 +62,14 @@ class ConfigSelector : public RefCounted { // The channel will call this when the resolver returns a new ConfigSelector // to determine what set of dynamic filters will be configured. - virtual void AddFilters(InterceptionChainBuilder& /*builder*/) {} + virtual void AddFilters(InterceptionChainBuilder& /*builder*/, + const Blackboard* /*old_blackboard*/, + Blackboard* /*new_blackboard*/) {} // TODO(roth): Remove this once the legacy filter stack goes away. - virtual std::vector GetFilters() { return {}; } + virtual std::vector GetFilters( + const Blackboard* /*old_blackboard*/, Blackboard* /*new_blackboard*/) { + return {}; + } // Gets the configuration for the call and stores it in service config // call data. diff --git a/deps/grpc/src/core/client_channel/dynamic_filters.cc b/deps/grpc/src/core/client_channel/dynamic_filters.cc index 21dbec9f5b3..ca65de6b9e2 100644 --- a/deps/grpc/src/core/client_channel/dynamic_filters.cc +++ b/deps/grpc/src/core/client_channel/dynamic_filters.cc @@ -137,9 +137,9 @@ namespace { absl::StatusOr> CreateChannelStack( const ChannelArgs& args, std::vector filters, - const Blackboard* old_blackboard, Blackboard* new_blackboard) { + const Blackboard* blackboard) { ChannelStackBuilderImpl builder("DynamicFilters", GRPC_CLIENT_DYNAMIC, args); - builder.SetBlackboards(old_blackboard, new_blackboard); + builder.SetBlackboard(blackboard); for (auto filter : filters) { builder.AppendFilter(filter); } @@ -150,16 +150,15 @@ absl::StatusOr> CreateChannelStack( RefCountedPtr DynamicFilters::Create( const ChannelArgs& args, std::vector filters, - const Blackboard* old_blackboard, Blackboard* new_blackboard) { + const Blackboard* blackboard) { // Attempt to create channel stack from requested filters. - auto p = CreateChannelStack(args, std::move(filters), old_blackboard, - new_blackboard); + auto p = CreateChannelStack(args, std::move(filters), blackboard); if (!p.ok()) { // Channel stack creation failed with requested filters. // Create with lame filter instead. auto error = p.status(); p = CreateChannelStack(args.Set(MakeLameClientErrorArg(&error)), - {&LameClientFilter::kFilter}, nullptr, nullptr); + {&LameClientFilter::kFilter}, nullptr); } return MakeRefCounted(std::move(p.value())); } diff --git a/deps/grpc/src/core/client_channel/dynamic_filters.h b/deps/grpc/src/core/client_channel/dynamic_filters.h index 001bcd45454..7e81a5d709f 100644 --- a/deps/grpc/src/core/client_channel/dynamic_filters.h +++ b/deps/grpc/src/core/client_channel/dynamic_filters.h @@ -90,7 +90,7 @@ class DynamicFilters final : public RefCounted { static RefCountedPtr Create( const ChannelArgs& args, std::vector filters, - const Blackboard* old_blackboard, Blackboard* new_blackboard); + const Blackboard* blackboard); explicit DynamicFilters(RefCountedPtr channel_stack) : channel_stack_(std::move(channel_stack)) {} diff --git a/deps/grpc/src/core/client_channel/global_subchannel_pool.cc b/deps/grpc/src/core/client_channel/global_subchannel_pool.cc index 2648a78908f..0091d96edf8 100644 --- a/deps/grpc/src/core/client_channel/global_subchannel_pool.cc +++ b/deps/grpc/src/core/client_channel/global_subchannel_pool.cc @@ -77,7 +77,10 @@ RefCountedPtr GlobalSubchannelPool::RegisterSubchannel( SubchannelMap old_map2; MutexLock lock(&write_shard.mu); auto* existing = write_shard.map.Lookup(key); - if (existing != nullptr) return (*existing)->RefIfNonZero(); + if (existing != nullptr) { + auto existing_ref = (*existing)->RefIfNonZero(); + if (existing_ref != nullptr) return existing_ref; + } old_map1 = std::exchange(write_shard.map, write_shard.map.Add(key, constructed->WeakRef())); MutexLock lock_read(&read_shard.mu); diff --git a/deps/grpc/src/core/client_channel/retry_filter.cc b/deps/grpc/src/core/client_channel/retry_filter.cc index 78a74f3102a..865da6afe2d 100644 --- a/deps/grpc/src/core/client_channel/retry_filter.cc +++ b/deps/grpc/src/core/client_channel/retry_filter.cc @@ -31,7 +31,6 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/iomgr/error.h" #include "src/core/service_config/service_config.h" #include "src/core/service_config/service_config_call_data.h" #include "src/core/util/ref_counted_ptr.h" @@ -93,39 +92,34 @@ namespace grpc_core { // RetryFilter // -RetryFilter::RetryFilter(const ChannelArgs& args, grpc_error_handle* error) - : client_channel_(args.GetObject()), - event_engine_(args.GetObject()), - per_rpc_retry_buffer_size_(GetMaxPerRpcRetryBufferSize(args)), - service_config_parser_index_( - internal::RetryServiceConfigParser::ParserIndex()) { +void RetryFilter::UpdateBlackboard(const ServiceConfig& service_config, + const Blackboard* old_blackboard, + Blackboard* new_blackboard) { // Get retry throttling parameters from service config. - auto* service_config = args.GetObject(); - if (service_config == nullptr) return; const auto* config = static_cast( - service_config->GetGlobalParsedConfig( + service_config.GetGlobalParsedConfig( RetryServiceConfigParser::ParserIndex())); if (config == nullptr) return; - // Get server name from target URI. - auto server_uri = args.GetString(GRPC_ARG_SERVER_URI); - if (!server_uri.has_value()) { - *error = GRPC_ERROR_CREATE( - "server URI channel arg missing or wrong type in client channel " - "filter"); - return; - } - absl::StatusOr uri = URI::Parse(*server_uri); - if (!uri.ok() || uri->path().empty()) { - *error = GRPC_ERROR_CREATE("could not extract server name from target URI"); - return; + // Get throttler. + RefCountedPtr throttler; + if (old_blackboard != nullptr) { + throttler = old_blackboard->Get(""); } - std::string server_name(absl::StripPrefix(uri->path(), "/")); - // Get throttling config for server_name. - retry_throttle_data_ = - internal::ServerRetryThrottleMap::Get()->GetDataForServer( - server_name, config->max_milli_tokens(), config->milli_token_ratio()); + throttler = internal::RetryThrottler::Create(config->max_milli_tokens(), + config->milli_token_ratio(), + std::move(throttler)); + new_blackboard->Set("", std::move(throttler)); } +RetryFilter::RetryFilter(const grpc_channel_element_args& args) + : client_channel_(args.channel_args.GetObject()), + event_engine_(args.channel_args.GetObject()), + per_rpc_retry_buffer_size_( + GetMaxPerRpcRetryBufferSize(args.channel_args)), + retry_throttler_(args.blackboard->Get("")), + service_config_parser_index_( + internal::RetryServiceConfigParser::ParserIndex()) {} + const RetryMethodConfig* RetryFilter::GetRetryPolicy(Arena* arena) { auto* svc_cfg_call_data = arena->GetContext(); if (svc_cfg_call_data == nullptr) return nullptr; diff --git a/deps/grpc/src/core/client_channel/retry_filter.h b/deps/grpc/src/core/client_channel/retry_filter.h index f7bc5d33a98..d683184b023 100644 --- a/deps/grpc/src/core/client_channel/retry_filter.h +++ b/deps/grpc/src/core/client_channel/retry_filter.h @@ -45,6 +45,10 @@ class RetryFilter final { public: static const grpc_channel_filter kVtable; + static void UpdateBlackboard(const ServiceConfig& service_config, + const Blackboard* old_blackboard, + Blackboard* blackboard); + private: // Old filter-stack style call implementation, in // retry_filter_legacy_call_data.{h,cc} @@ -60,8 +64,8 @@ class RetryFilter final { const internal::RetryMethodConfig* GetRetryPolicy(Arena* arena); - RefCountedPtr retry_throttle_data() const { - return retry_throttle_data_; + RefCountedPtr retry_throttler() const { + return retry_throttler_; } ClientChannelFilter* client_channel() const { return client_channel_; } @@ -80,15 +84,14 @@ class RetryFilter final { 0, INT_MAX); } - RetryFilter(const ChannelArgs& args, grpc_error_handle* error); + explicit RetryFilter(const grpc_channel_element_args& args); static grpc_error_handle Init(grpc_channel_element* elem, grpc_channel_element_args* args) { CHECK(args->is_last); CHECK(elem->filter == &kVtable); - grpc_error_handle error; - new (elem->channel_data) RetryFilter(args->channel_args, &error); - return error; + new (elem->channel_data) RetryFilter(*args); + return absl::OkStatus(); } static void Destroy(grpc_channel_element* elem) { @@ -105,7 +108,7 @@ class RetryFilter final { ClientChannelFilter* client_channel_; grpc_event_engine::experimental::EventEngine* const event_engine_; size_t per_rpc_retry_buffer_size_; - RefCountedPtr retry_throttle_data_; + RefCountedPtr retry_throttler_; const size_t service_config_parser_index_; }; diff --git a/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.cc b/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.cc index 004f9e76816..60e6ed53e5b 100644 --- a/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.cc +++ b/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.cc @@ -537,8 +537,8 @@ bool RetryFilter::LegacyCallData::CallAttempt::ShouldRetry( // Check status. if (status.has_value()) { if (GPR_LIKELY(*status == GRPC_STATUS_OK)) { - if (calld_->retry_throttle_data_ != nullptr) { - calld_->retry_throttle_data_->RecordSuccess(); + if (calld_->retry_throttler_ != nullptr) { + calld_->retry_throttler_->RecordSuccess(); } GRPC_TRACE_LOG(retry, INFO) << "chand=" << calld_->chand_ << " calld=" << calld_ @@ -562,8 +562,8 @@ bool RetryFilter::LegacyCallData::CallAttempt::ShouldRetry( // things like failures due to malformed requests (INVALID_ARGUMENT). // Conversely, it's important for this to come before the remaining // checks, so that we don't fail to record failures due to other factors. - if (calld_->retry_throttle_data_ != nullptr && - !calld_->retry_throttle_data_->RecordFailure()) { + if (calld_->retry_throttler_ != nullptr && + !calld_->retry_throttler_->RecordFailure()) { GRPC_TRACE_LOG(retry, INFO) << "chand=" << calld_->chand_ << " calld=" << calld_ << " attempt=" << this << ": retries throttled"; @@ -1471,7 +1471,7 @@ void RetryFilter::LegacyCallData::SetPollent(grpc_call_element* elem, RetryFilter::LegacyCallData::LegacyCallData(RetryFilter* chand, const grpc_call_element_args& args) : chand_(chand), - retry_throttle_data_(chand->retry_throttle_data()), + retry_throttler_(chand->retry_throttler()), retry_policy_(chand->GetRetryPolicy(args.arena)), retry_backoff_( BackOff::Options() diff --git a/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.h b/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.h index d830289b53b..c36ebd5ece5 100644 --- a/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.h +++ b/deps/grpc/src/core/client_channel/retry_filter_legacy_call_data.h @@ -370,7 +370,7 @@ class RetryFilter::LegacyCallData final { RetryFilter* chand_; grpc_polling_entity* pollent_; - RefCountedPtr retry_throttle_data_; + RefCountedPtr retry_throttler_; const internal::RetryMethodConfig* retry_policy_ = nullptr; BackOff retry_backoff_; diff --git a/deps/grpc/src/core/client_channel/retry_interceptor.cc b/deps/grpc/src/core/client_channel/retry_interceptor.cc index 11f42b5de5c..d894f920317 100644 --- a/deps/grpc/src/core/client_channel/retry_interceptor.cc +++ b/deps/grpc/src/core/client_channel/retry_interceptor.cc @@ -35,11 +35,10 @@ size_t GetMaxPerRpcRetryBufferSize(const ChannelArgs& args) { namespace retry_detail { -RetryState::RetryState( - const internal::RetryMethodConfig* retry_policy, - RefCountedPtr retry_throttle_data) +RetryState::RetryState(const internal::RetryMethodConfig* retry_policy, + RefCountedPtr retry_throttler) : retry_policy_(retry_policy), - retry_throttle_data_(std::move(retry_throttle_data)), + retry_throttler_(std::move(retry_throttler)), retry_backoff_( BackOff::Options() .set_initial_backoff(retry_policy_ == nullptr @@ -67,8 +66,8 @@ std::optional RetryState::ShouldRetry( const auto status = md.get(GrpcStatusMetadata()); if (status.has_value()) { if (GPR_LIKELY(*status == GRPC_STATUS_OK)) { - if (retry_throttle_data_ != nullptr) { - retry_throttle_data_->RecordSuccess(); + if (retry_throttler_ != nullptr) { + retry_throttler_->RecordSuccess(); } GRPC_TRACE_LOG(retry, INFO) << lazy_attempt_debug_string() << " call succeeded"; @@ -89,8 +88,7 @@ std::optional RetryState::ShouldRetry( // things like failures due to malformed requests (INVALID_ARGUMENT). // Conversely, it's important for this to come before the remaining // checks, so that we don't fail to record failures due to other factors. - if (retry_throttle_data_ != nullptr && - !retry_throttle_data_->RecordFailure()) { + if (retry_throttler_ != nullptr && !retry_throttler_->RecordFailure()) { GRPC_TRACE_LOG(retry, INFO) << lazy_attempt_debug_string() << " retries throttled"; return std::nullopt; @@ -131,55 +129,43 @@ std::optional RetryState::ShouldRetry( return next_attempt_timeout; } -absl::StatusOr> -ServerRetryThrottleDataFromChannelArgs(const ChannelArgs& args) { - // Get retry throttling parameters from service config. - auto* service_config = args.GetObject(); - if (service_config == nullptr) return nullptr; - const auto* config = static_cast( - service_config->GetGlobalParsedConfig( - internal::RetryServiceConfigParser::ParserIndex())); - if (config == nullptr) return nullptr; - // Get server name from target URI. - auto server_uri = args.GetString(GRPC_ARG_SERVER_URI); - if (!server_uri.has_value()) { - return GRPC_ERROR_CREATE( - "server URI channel arg missing or wrong type in client channel " - "filter"); - } - absl::StatusOr uri = URI::Parse(*server_uri); - if (!uri.ok() || uri->path().empty()) { - return GRPC_ERROR_CREATE("could not extract server name from target URI"); - } - std::string server_name(absl::StripPrefix(uri->path(), "/")); - // Get throttling config for server_name. - return internal::ServerRetryThrottleMap::Get()->GetDataForServer( - server_name, config->max_milli_tokens(), config->milli_token_ratio()); -} - } // namespace retry_detail //////////////////////////////////////////////////////////////////////////////// // RetryInterceptor absl::StatusOr> RetryInterceptor::Create( - const ChannelArgs& args, const FilterArgs&) { - auto retry_throttle_data = - retry_detail::ServerRetryThrottleDataFromChannelArgs(args); - if (!retry_throttle_data.ok()) { - return retry_throttle_data.status(); + const ChannelArgs& args, const FilterArgs& filter_args) { + auto retry_throttler = filter_args.GetState(""); + return MakeRefCounted(args, std::move(retry_throttler)); +} + +void RetryInterceptor::UpdateBlackboard(const ServiceConfig& service_config, + const Blackboard* old_blackboard, + Blackboard* new_blackboard) { + const auto* config = static_cast( + service_config.GetGlobalParsedConfig( + internal::RetryServiceConfigParser::ParserIndex())); + if (config == nullptr) return; + // Get existing throttle state. + RefCountedPtr throttler; + if (old_blackboard != nullptr) { + throttler = old_blackboard->Get(""); } - return MakeRefCounted(args, - std::move(*retry_throttle_data)); + throttler = internal::RetryThrottler::Create(config->max_milli_tokens(), + config->milli_token_ratio(), + std::move(throttler)); + CHECK_NE(new_blackboard, nullptr); + new_blackboard->Set("", std::move(throttler)); } RetryInterceptor::RetryInterceptor( const ChannelArgs& args, - RefCountedPtr retry_throttle_data) + RefCountedPtr retry_throttler) : per_rpc_retry_buffer_size_(GetMaxPerRpcRetryBufferSize(args)), service_config_parser_index_( internal::RetryServiceConfigParser::ParserIndex()), - retry_throttle_data_(std::move(retry_throttle_data)) {} + retry_throttler_(std::move(retry_throttler)) {} void RetryInterceptor::InterceptCall( UnstartedCallHandler unstarted_call_handler) { @@ -206,7 +192,7 @@ RetryInterceptor::Call::Call(RefCountedPtr interceptor, : call_handler_(std::move(call_handler)), interceptor_(std::move(interceptor)), retry_state_(interceptor_->GetRetryPolicy(), - interceptor_->retry_throttle_data_) { + interceptor_->retry_throttler_) { GRPC_TRACE_LOG(retry, INFO) << DebugTag() << " retry call created: " << retry_state_; } diff --git a/deps/grpc/src/core/client_channel/retry_interceptor.h b/deps/grpc/src/core/client_channel/retry_interceptor.h index afdf0ce5192..cfb1b5ae732 100644 --- a/deps/grpc/src/core/client_channel/retry_interceptor.h +++ b/deps/grpc/src/core/client_channel/retry_interceptor.h @@ -26,11 +26,11 @@ namespace grpc_core { namespace retry_detail { + class RetryState { public: - RetryState( - const internal::RetryMethodConfig* retry_policy, - RefCountedPtr retry_throttle_data); + RetryState(const internal::RetryMethodConfig* retry_policy, + RefCountedPtr retry_throttler); // if nullopt --> commit & don't retry // if duration --> retry after duration @@ -41,36 +41,37 @@ class RetryState { template friend void AbslStringify(Sink& sink, const RetryState& state) { - sink.Append(absl::StrCat( - "policy:{", - state.retry_policy_ != nullptr ? absl::StrCat(*state.retry_policy_) - : "none", - "} throttle:", state.retry_throttle_data_ != nullptr, - " attempts:", state.num_attempts_completed_)); + sink.Append(absl::StrCat("policy:{", + state.retry_policy_ != nullptr + ? absl::StrCat(*state.retry_policy_) + : "none", + "} throttler:", state.retry_throttler_ != nullptr, + " attempts:", state.num_attempts_completed_)); } private: const internal::RetryMethodConfig* const retry_policy_; - RefCountedPtr retry_throttle_data_; + RefCountedPtr retry_throttler_; int num_attempts_completed_ = 0; BackOff retry_backoff_; }; -absl::StatusOr> -ServerRetryThrottleDataFromChannelArgs(const ChannelArgs& args); } // namespace retry_detail class RetryInterceptor : public Interceptor { public: - RetryInterceptor( - const ChannelArgs& args, - RefCountedPtr retry_throttle_data); + RetryInterceptor(const ChannelArgs& args, + RefCountedPtr retry_throttler); static absl::StatusOr> Create( - const ChannelArgs& args, const FilterArgs&); + const ChannelArgs& args, const FilterArgs& filter_args); void Orphaned() override {} + static void UpdateBlackboard(const ServiceConfig& service_config, + const Blackboard* old_blackboard, + Blackboard* new_blackboard); + protected: void InterceptCall(UnstartedCallHandler unstarted_call_handler) override; @@ -149,7 +150,7 @@ class RetryInterceptor : public Interceptor { const size_t per_rpc_retry_buffer_size_; const size_t service_config_parser_index_; - const RefCountedPtr retry_throttle_data_; + const RefCountedPtr retry_throttler_; }; } // namespace grpc_core diff --git a/deps/grpc/src/core/client_channel/retry_throttle.cc b/deps/grpc/src/core/client_channel/retry_throttle.cc index 5e7b6b04923..7590116cc35 100644 --- a/deps/grpc/src/core/client_channel/retry_throttle.cc +++ b/deps/grpc/src/core/client_channel/retry_throttle.cc @@ -18,14 +18,9 @@ #include "src/core/client_channel/retry_throttle.h" -#include - #include #include #include -#include -#include -#include #include "src/core/util/useful.h" @@ -33,6 +28,7 @@ namespace grpc_core { namespace internal { namespace { + template T ClampedAdd(std::atomic& value, T delta, T min, T max) { T prev_value = value.load(std::memory_order_relaxed); @@ -43,45 +39,74 @@ T ClampedAdd(std::atomic& value, T delta, T min, T max) { std::memory_order_relaxed)); return new_value; } + } // namespace // -// ServerRetryThrottleData +// RetryThrottler // -ServerRetryThrottleData::ServerRetryThrottleData(uintptr_t max_milli_tokens, - uintptr_t milli_token_ratio, - uintptr_t milli_tokens) +RefCountedPtr RetryThrottler::Create( + uintptr_t max_milli_tokens, uintptr_t milli_token_ratio, + RefCountedPtr previous) { + if (previous != nullptr && previous->max_milli_tokens_ == max_milli_tokens && + previous->milli_token_ratio_ == milli_token_ratio) { + return previous; + } + // previous is null or has different parameters. Create a new one. + uintptr_t initial_milli_tokens = max_milli_tokens; + // If there was a pre-existing entry for this server name, initialize + // the token count by scaling proportionately to the old data. This + // ensures that if we're already throttling retries on the old scale, + // we will start out doing the same thing on the new one. + if (previous != nullptr) { + double token_fraction = static_cast(previous->milli_tokens_) / + static_cast(previous->max_milli_tokens_); + initial_milli_tokens = + static_cast(token_fraction * max_milli_tokens); + } + auto throttle_data = MakeRefCounted( + max_milli_tokens, milli_token_ratio, initial_milli_tokens); + if (previous != nullptr) previous->SetReplacement(throttle_data); + return throttle_data; +} + +UniqueTypeName RetryThrottler::Type() { + static UniqueTypeName::Factory factory("retry_throttle"); + return factory.Create(); +} + +RetryThrottler::RetryThrottler(uintptr_t max_milli_tokens, + uintptr_t milli_token_ratio, + uintptr_t milli_tokens) : max_milli_tokens_(max_milli_tokens), milli_token_ratio_(milli_token_ratio), milli_tokens_(milli_tokens) {} -ServerRetryThrottleData::~ServerRetryThrottleData() { - ServerRetryThrottleData* replacement = - replacement_.load(std::memory_order_acquire); +RetryThrottler::~RetryThrottler() { + RetryThrottler* replacement = replacement_.load(std::memory_order_acquire); if (replacement != nullptr) { replacement->Unref(); } } -void ServerRetryThrottleData::SetReplacement( - RefCountedPtr replacement) { +void RetryThrottler::SetReplacement(RefCountedPtr replacement) { replacement_.store(replacement.release(), std::memory_order_release); } -void ServerRetryThrottleData::GetReplacementThrottleDataIfNeeded( - ServerRetryThrottleData** throttle_data) { +void RetryThrottler::GetReplacementThrottleDataIfNeeded( + RetryThrottler** throttle_data) { while (true) { - ServerRetryThrottleData* new_throttle_data = + RetryThrottler* new_throttle_data = (*throttle_data)->replacement_.load(std::memory_order_acquire); if (new_throttle_data == nullptr) return; *throttle_data = new_throttle_data; } } -bool ServerRetryThrottleData::RecordFailure() { +bool RetryThrottler::RecordFailure() { // First, check if we are stale and need to be replaced. - ServerRetryThrottleData* throttle_data = this; + RetryThrottler* throttle_data = this; GetReplacementThrottleDataIfNeeded(&throttle_data); // We decrement milli_tokens by 1000 (1 token) for each failure. const uintptr_t new_value = ClampedAdd( @@ -93,9 +118,9 @@ bool ServerRetryThrottleData::RecordFailure() { return new_value > throttle_data->max_milli_tokens_ / 2; } -void ServerRetryThrottleData::RecordSuccess() { +void RetryThrottler::RecordSuccess() { // First, check if we are stale and need to be replaced. - ServerRetryThrottleData* throttle_data = this; + RetryThrottler* throttle_data = this; GetReplacementThrottleDataIfNeeded(&throttle_data); // We increment milli_tokens by milli_token_ratio for each success. ClampedAdd( @@ -105,45 +130,5 @@ void ServerRetryThrottleData::RecordSuccess() { std::numeric_limits::max()))); } -// -// ServerRetryThrottleMap -// - -ServerRetryThrottleMap* ServerRetryThrottleMap::Get() { - static ServerRetryThrottleMap* m = new ServerRetryThrottleMap(); - return m; -} - -RefCountedPtr ServerRetryThrottleMap::GetDataForServer( - const std::string& server_name, uintptr_t max_milli_tokens, - uintptr_t milli_token_ratio) { - MutexLock lock(&mu_); - auto& throttle_data = map_[server_name]; - if (throttle_data == nullptr || - throttle_data->max_milli_tokens() != max_milli_tokens || - throttle_data->milli_token_ratio() != milli_token_ratio) { - // Entry not found, or found with old parameters. Create a new one. - auto old_throttle_data = std::move(throttle_data); - uintptr_t initial_milli_tokens = max_milli_tokens; - // If there was a pre-existing entry for this server name, initialize - // the token count by scaling proportionately to the old data. This - // ensures that if we're already throttling retries on the old scale, - // we will start out doing the same thing on the new one. - if (old_throttle_data != nullptr) { - double token_fraction = - static_cast(old_throttle_data->milli_tokens()) / - static_cast(old_throttle_data->max_milli_tokens()); - initial_milli_tokens = - static_cast(token_fraction * max_milli_tokens); - } - throttle_data = MakeRefCounted( - max_milli_tokens, milli_token_ratio, initial_milli_tokens); - if (old_throttle_data != nullptr) { - old_throttle_data->SetReplacement(throttle_data); - } - } - return throttle_data; -} - } // namespace internal } // namespace grpc_core diff --git a/deps/grpc/src/core/client_channel/retry_throttle.h b/deps/grpc/src/core/client_channel/retry_throttle.h index 0ce52c6dedf..f6be450c9ec 100644 --- a/deps/grpc/src/core/client_channel/retry_throttle.h +++ b/deps/grpc/src/core/client_channel/retry_throttle.h @@ -19,30 +19,29 @@ #ifndef GRPC_SRC_CORE_CLIENT_CHANNEL_RETRY_THROTTLE_H #define GRPC_SRC_CORE_CLIENT_CHANNEL_RETRY_THROTTLE_H -#include #include #include -#include -#include -#include "absl/base/thread_annotations.h" -#include "src/core/util/ref_counted.h" +#include "src/core/filter/blackboard.h" #include "src/core/util/ref_counted_ptr.h" -#include "src/core/util/sync.h" namespace grpc_core { namespace internal { -class ServerRetryThrottleMap; - /// Tracks retry throttling data for an individual server name. -class ServerRetryThrottleData final - : public RefCounted { +class RetryThrottler final : public Blackboard::Entry { public: - ServerRetryThrottleData(uintptr_t max_milli_tokens, - uintptr_t milli_token_ratio, uintptr_t milli_tokens); - ~ServerRetryThrottleData() override; + static RefCountedPtr Create( + uintptr_t max_milli_tokens, uintptr_t milli_token_ratio, + RefCountedPtr previous); + + static UniqueTypeName Type(); + + // Do not instantiate directly -- use Create() instead. + RetryThrottler(uintptr_t max_milli_tokens, uintptr_t milli_token_ratio, + uintptr_t milli_tokens); + ~RetryThrottler() override; /// Records a failure. Returns true if it's okay to send a retry. bool RecordFailure(); @@ -50,6 +49,7 @@ class ServerRetryThrottleData final /// Records a success. void RecordSuccess(); + // Exposed for testing purposes only. uintptr_t max_milli_tokens() const { return max_milli_tokens_; } uintptr_t milli_token_ratio() const { return milli_token_ratio_; } intptr_t milli_tokens() const { @@ -57,39 +57,17 @@ class ServerRetryThrottleData final } private: - friend ServerRetryThrottleMap; + void SetReplacement(RefCountedPtr replacement); - void SetReplacement(RefCountedPtr replacement); - - void GetReplacementThrottleDataIfNeeded( - ServerRetryThrottleData** throttle_data); + void GetReplacementThrottleDataIfNeeded(RetryThrottler** throttle_data); const uintptr_t max_milli_tokens_; const uintptr_t milli_token_ratio_; std::atomic milli_tokens_; - // A pointer to the replacement for this ServerRetryThrottleData entry. + // A pointer to the replacement for this RetryThrottler entry. // If non-nullptr, then this entry is stale and must not be used. // We hold a reference to the replacement. - std::atomic replacement_{nullptr}; -}; - -/// Global map of server name to retry throttle data. -class ServerRetryThrottleMap final { - public: - static ServerRetryThrottleMap* Get(); - - /// Returns the failure data for \a server_name, creating a new entry if - /// needed. - RefCountedPtr GetDataForServer( - const std::string& server_name, uintptr_t max_milli_tokens, - uintptr_t milli_token_ratio); - - private: - using StringToDataMap = - std::map>; - - Mutex mu_; - StringToDataMap map_ ABSL_GUARDED_BY(mu_); + std::atomic replacement_{nullptr}; }; } // namespace internal diff --git a/deps/grpc/src/core/client_channel/subchannel.cc b/deps/grpc/src/core/client_channel/subchannel.cc index 2461177610f..643a1a7b12c 100644 --- a/deps/grpc/src/core/client_channel/subchannel.cc +++ b/deps/grpc/src/core/client_channel/subchannel.cc @@ -422,11 +422,21 @@ class Subchannel::ConnectedSubchannelStateWatcher final if (c->channelz_node() != nullptr) { c->channelz_node()->SetChildSocket(nullptr); } - // Even though we're reporting IDLE instead of TRANSIENT_FAILURE here, - // pass along the status from the transport, since it may have - // keepalive info attached to it that the channel needs. - // TODO(roth): Consider whether there's a cleaner way to do this. - c->SetConnectivityStateLocked(GRPC_CHANNEL_IDLE, status); + // If the subchannel was created from an endpoint, then we report + // TRANSIENT_FAILURE here instead of IDLE. The subchannel will never + // leave TRANSIENT_FAILURE state, because there is no way for us to + // establish a new connection. + // + // Otherwise, we report IDLE here. Note that even though we're not + // reporting TRANSIENT_FAILURE, we pass along the status from the + // transport, since it may have keepalive info attached to it that the + // channel needs. + // TODO(roth): Consider whether there's a cleaner way to propagate the + // keepalive info. + c->SetConnectivityStateLocked(c->created_from_endpoint_ + ? GRPC_CHANNEL_TRANSIENT_FAILURE + : GRPC_CHANNEL_IDLE, + status); c->backoff_.Reset(); } } @@ -509,6 +519,7 @@ Subchannel::Subchannel(SubchannelKey key, ? "Subchannel" : nullptr), key_(std::move(key)), + created_from_endpoint_(args.Contains(GRPC_ARG_SUBCHANNEL_ENDPOINT)), args_(args), pollset_set_(grpc_pollset_set_create()), connector_(std::move(connector)), @@ -546,9 +557,7 @@ Subchannel::Subchannel(SubchannelKey key, grpc_sockaddr_to_uri(&key_.address()) .value_or(""), channel_tracer_max_memory); - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("subchannel created")); + GRPC_CHANNELZ_LOG(channelz_node_) << "subchannel created"; channelz_node_->SetChannelArgs(args_); args_ = args_.SetObject(channelz_node_); } @@ -556,9 +565,7 @@ Subchannel::Subchannel(SubchannelKey key, Subchannel::~Subchannel() { if (channelz_node_ != nullptr) { - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel destroyed")); + GRPC_CHANNELZ_LOG(channelz_node_) << "Subchannel destroyed"; channelz_node_->UpdateConnectivityState(GRPC_CHANNEL_SHUTDOWN); } connector_.reset(); @@ -578,6 +585,15 @@ RefCountedPtr Subchannel::Create( return c; } c = MakeRefCounted(std::move(key), std::move(connector), args); + if (c->created_from_endpoint_) { + // We don't interact with the subchannel pool in this case. + // Instead, we unconditionally return the newly created subchannel. + // Before returning, we explicitly trigger a connection attempt + // by calling RequestConnection(), which sets the subchannel’s + // connectivity state to CONNECTING. + c->RequestConnection(); + return c; + } // Try to register the subchannel before setting the subchannel pool. // Otherwise, in case of a registration race, unreffing c in // RegisterSubchannel() will cause c to be tried to be unregistered, while @@ -702,12 +718,15 @@ void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, } if (channelz_node_ != nullptr) { channelz_node_->UpdateConnectivityState(state); - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_cpp_string(absl::StrCat( - "Subchannel connectivity state changed to ", - ConnectivityStateName(state), - status.ok() ? "" : absl::StrCat(": ", status_.ToString())))); + if (status.ok()) { + GRPC_CHANNELZ_LOG(channelz_node_) + << "Subchannel connectivity state changed to " + << ConnectivityStateName(state); + } else { + GRPC_CHANNELZ_LOG(channelz_node_) + << "Subchannel connectivity state changed to " + << ConnectivityStateName(state) << ": " << status; + } } // Notify watchers. watcher_list_.NotifyLocked(state, status_); @@ -767,10 +786,15 @@ void Subchannel::OnConnectingFinishedLocked(grpc_error_handle error) { next_attempt_time_ - Timestamp::Now(); GRPC_TRACE_LOG(subchannel, INFO) << "subchannel " << this << " " << key_.ToString() - << ": connect failed (" << StatusToString(error) - << "), backing off for " << time_until_next_attempt.millis() << " ms"; + << ": connect failed (" << StatusToString(error) << ")" + << (created_from_endpoint_ + ? ", no retry will be attempted (created from endpoint); " + "remaining in TRANSIENT_FAILURE" + : ", backing off for " + + std::to_string(time_until_next_attempt.millis()) + " ms"); SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error)); + if (created_from_endpoint_) return; retry_timer_handle_ = event_engine_->RunAfter( time_until_next_attempt, [self = WeakRef(DEBUG_LOCATION, "RetryTimer")]() mutable { diff --git a/deps/grpc/src/core/client_channel/subchannel.h b/deps/grpc/src/core/client_channel/subchannel.h index 63b149e94d3..1392f5c2854 100644 --- a/deps/grpc/src/core/client_channel/subchannel.h +++ b/deps/grpc/src/core/client_channel/subchannel.h @@ -58,6 +58,11 @@ #include "src/core/util/unique_type_name.h" #include "src/core/util/work_serializer.h" +/** This arg is intended for internal use only, primarily + * for passing endpoint information during subchannel creation or connection. + */ +#define GRPC_ARG_SUBCHANNEL_ENDPOINT "grpc.internal.subchannel_endpoint" + namespace grpc_core { class SubchannelCall; @@ -328,6 +333,9 @@ class Subchannel final : public DualRefCounted { RefCountedPtr subchannel_pool_; // Subchannel key that identifies this subchannel in the subchannel pool. const SubchannelKey key_; + // boolean value that identifies this subchannel is created from event engine + // endpoint. + const bool created_from_endpoint_; // Actual address to connect to. May be different than the address in // key_ if overridden by proxy mapper. grpc_resolved_address address_for_connect_; diff --git a/deps/grpc/src/core/config/config_vars.cc b/deps/grpc/src/core/config/config_vars.cc index 07d991c7fef..3c0e59b5b50 100644 --- a/deps/grpc/src/core/config/config_vars.cc +++ b/deps/grpc/src/core/config/config_vars.cc @@ -30,7 +30,9 @@ #endif // !GPR_DEFAULT_LOG_VERBOSITY_STRING #ifdef GRPC_ENABLE_FORK_SUPPORT +#ifndef GRPC_ENABLE_FORK_SUPPORT_DEFAULT #define GRPC_ENABLE_FORK_SUPPORT_DEFAULT true +#endif // !defined(GRPC_ENABLE_FORK_SUPPORT_DEFAULT) #else #define GRPC_ENABLE_FORK_SUPPORT_DEFAULT false #endif // GRPC_ENABLE_FORK_SUPPORT diff --git a/deps/grpc/src/core/config/config_vars.yaml b/deps/grpc/src/core/config/config_vars.yaml index 129d481d07a..d0ec8ee0ad3 100644 --- a/deps/grpc/src/core/config/config_vars.yaml +++ b/deps/grpc/src/core/config/config_vars.yaml @@ -75,7 +75,9 @@ description: Enable fork support prelude: | #ifdef GRPC_ENABLE_FORK_SUPPORT + #ifndef GRPC_ENABLE_FORK_SUPPORT_DEFAULT #define GRPC_ENABLE_FORK_SUPPORT_DEFAULT true + #endif // !defined(GRPC_ENABLE_FORK_SUPPORT_DEFAULT) #else #define GRPC_ENABLE_FORK_SUPPORT_DEFAULT false #endif // GRPC_ENABLE_FORK_SUPPORT diff --git a/deps/grpc/src/core/config/core_configuration.cc b/deps/grpc/src/core/config/core_configuration.cc index 34d5465f64d..94dfeac0c6e 100644 --- a/deps/grpc/src/core/config/core_configuration.cc +++ b/deps/grpc/src/core/config/core_configuration.cc @@ -43,6 +43,7 @@ CoreConfiguration::CoreConfiguration(Builder* builder) channel_init_(builder->channel_init_.Build()), handshaker_registry_(builder->handshaker_registry_.Build()), channel_creds_registry_(builder->channel_creds_registry_.Build()), + call_creds_registry_(builder->call_creds_registry_.Build()), service_config_parser_(builder->service_config_parser_.Build()), resolver_registry_(builder->resolver_registry_.Build()), lb_policy_registry_(builder->lb_policy_registry_.Build()), diff --git a/deps/grpc/src/core/config/core_configuration.h b/deps/grpc/src/core/config/core_configuration.h index 9eeb96a6cdf..b3522d92948 100644 --- a/deps/grpc/src/core/config/core_configuration.h +++ b/deps/grpc/src/core/config/core_configuration.h @@ -22,6 +22,7 @@ #include "absl/functional/any_invocable.h" #include "absl/log/check.h" +#include "src/core/credentials/call/call_creds_registry.h" #include "src/core/credentials/transport/channel_creds_registry.h" #include "src/core/credentials/transport/tls/certificate_provider_registry.h" #include "src/core/handshaker/handshaker_registry.h" @@ -82,6 +83,10 @@ class GRPC_DLL CoreConfiguration { return &channel_creds_registry_; } + CallCredsRegistry<>::Builder* call_creds_registry() { + return &call_creds_registry_; + } + ServiceConfigParser::Builder* service_config_parser() { return &service_config_parser_; } @@ -113,6 +118,7 @@ class GRPC_DLL CoreConfiguration { ChannelInit::Builder channel_init_; HandshakerRegistry::Builder handshaker_registry_; ChannelCredsRegistry<>::Builder channel_creds_registry_; + CallCredsRegistry<>::Builder call_creds_registry_; ServiceConfigParser::Builder service_config_parser_; ResolverRegistry::Builder resolver_registry_; LoadBalancingPolicyRegistry::Builder lb_policy_registry_; @@ -241,6 +247,10 @@ class GRPC_DLL CoreConfiguration { return channel_creds_registry_; } + const CallCredsRegistry<>& call_creds_registry() const { + return call_creds_registry_; + } + const ServiceConfigParser& service_config_parser() const { return service_config_parser_; } @@ -292,6 +302,7 @@ class GRPC_DLL CoreConfiguration { ChannelInit channel_init_; HandshakerRegistry handshaker_registry_; ChannelCredsRegistry<> channel_creds_registry_; + CallCredsRegistry<> call_creds_registry_; ServiceConfigParser service_config_parser_; ResolverRegistry resolver_registry_; LoadBalancingPolicyRegistry lb_policy_registry_; diff --git a/deps/grpc/src/core/credentials/call/call_creds_registry.h b/deps/grpc/src/core/credentials/call/call_creds_registry.h new file mode 100644 index 00000000000..dee6b3d7792 --- /dev/null +++ b/deps/grpc/src/core/credentials/call/call_creds_registry.h @@ -0,0 +1,125 @@ +// +// Copyright 2025 gRPC authors. +// +// 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. +// + +#ifndef GRPC_SRC_CORE_CREDENTIALS_CALL_CALL_CREDS_REGISTRY_H +#define GRPC_SRC_CORE_CREDENTIALS_CALL_CALL_CREDS_REGISTRY_H + +#include +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "src/core/util/json/json.h" +#include "src/core/util/json/json_args.h" +#include "src/core/util/ref_counted.h" +#include "src/core/util/ref_counted_ptr.h" +#include "src/core/util/validation_errors.h" + +struct grpc_call_credentials; + +namespace grpc_core { + +class CallCredsConfig : public RefCounted { + public: + virtual absl::string_view type() const = 0; + + virtual bool Equals(const CallCredsConfig& other) const = 0; + + virtual std::string ToString() const = 0; +}; + +template +class CallCredsFactory final { + public: + virtual ~CallCredsFactory() {} + virtual absl::string_view type() const = delete; + virtual RefCountedPtr ParseConfig( + const Json& config, const JsonArgs& args, + ValidationErrors* errors) const = delete; + virtual RefCountedPtr CreateCallCreds( + RefCountedPtr config) const = delete; +}; + +template <> +class CallCredsFactory { + public: + virtual ~CallCredsFactory() {} + virtual absl::string_view type() const = 0; + virtual RefCountedPtr ParseConfig( + const Json& config, const JsonArgs& args, + ValidationErrors* errors) const = 0; + virtual RefCountedPtr CreateCallCreds( + RefCountedPtr config) const = 0; +}; + +template +class CallCredsRegistry { + private: + using FactoryMap = + std::map>>; + + public: + static_assert(std::is_base_of::value, + "CallCredsRegistry must be instantiated with " + "grpc_call_credentials."); + + class Builder { + public: + void RegisterCallCredsFactory( + std::unique_ptr> factory) { + absl::string_view type = factory->type(); + factories_[type] = std::move(factory); + } + CallCredsRegistry Build() { + return CallCredsRegistry(std::move(factories_)); + } + + private: + FactoryMap factories_; + }; + + bool IsSupported(absl::string_view type) const { + return factories_.find(type) != factories_.end(); + } + + RefCountedPtr ParseConfig(absl::string_view type, + const Json& config, + const JsonArgs& args, + ValidationErrors* errors) const { + const auto it = factories_.find(type); + if (it == factories_.cend()) return nullptr; + return it->second->ParseConfig(config, args, errors); + } + + RefCountedPtr CreateCallCreds( + RefCountedPtr config) const { + if (config == nullptr) return nullptr; + const auto it = factories_.find(config->type()); + if (it == factories_.cend()) return nullptr; + return it->second->CreateCallCreds(std::move(config)); + } + + private: + explicit CallCredsRegistry(FactoryMap factories) + : factories_(std::move(factories)) {} + + FactoryMap factories_; +}; + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_CREDENTIALS_CALL_CALL_CREDS_REGISTRY_H diff --git a/deps/grpc/src/core/credentials/call/call_creds_registry_init.cc b/deps/grpc/src/core/credentials/call/call_creds_registry_init.cc new file mode 100644 index 00000000000..637d3aef138 --- /dev/null +++ b/deps/grpc/src/core/credentials/call/call_creds_registry_init.cc @@ -0,0 +1,91 @@ +// +// Copyright 2025 gRPC authors. +// +// 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. +// + +#include +#include +#include +#include + +#include +#include + +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "src/core/config/core_configuration.h" +#include "src/core/credentials/call/call_credentials.h" +#include "src/core/credentials/call/call_creds_registry.h" +#include "src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h" +#include "src/core/util/down_cast.h" +#include "src/core/util/json/json.h" +#include "src/core/util/json/json_args.h" +#include "src/core/util/json/json_object_loader.h" +#include "src/core/util/ref_counted_ptr.h" +#include "src/core/util/validation_errors.h" + +namespace grpc_core { + +class JwtTokenFileCallCredsFactory : public CallCredsFactory<> { + public: + absl::string_view type() const override { return Type(); } + + RefCountedPtr ParseConfig( + const Json& config, const JsonArgs& args, + ValidationErrors* errors) const override { + return LoadFromJson>(config, args, errors); + } + + RefCountedPtr CreateCallCreds( + RefCountedPtr base_config) const override { + auto* config = DownCast(base_config.get()); + return MakeRefCounted(config->path()); + } + + private: + class Config : public CallCredsConfig { + public: + absl::string_view type() const override { return Type(); } + + bool Equals(const CallCredsConfig& other) const override { + auto& o = DownCast(other); + return path_ == o.path_; + } + + std::string ToString() const override { + return absl::StrCat("{path=\"", path_, "\"}"); + } + + const std::string& path() const { return path_; } + + static const JsonLoaderInterface* JsonLoader(const JsonArgs&) { + static const auto* loader = JsonObjectLoader() + .Field("jwt_token_file", &Config::path_) + .Finish(); + return loader; + } + + private: + std::string path_; + }; + + static absl::string_view Type() { return "jwt_token_file"; } +}; + +void RegisterDefaultCallCreds(CoreConfiguration::Builder* builder) { + builder->call_creds_registry()->RegisterCallCredsFactory( + std::make_unique()); +} + +} // namespace grpc_core diff --git a/deps/grpc/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc b/deps/grpc/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc index 268d174d336..725ae313005 100644 --- a/deps/grpc/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +++ b/deps/grpc/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc @@ -16,23 +16,16 @@ #include "src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h" -#include - #include "absl/functional/any_invocable.h" #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" -#include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "src/core/call/metadata.h" +#include "src/core/credentials/call/jwt_util.h" #include "src/core/credentials/transport/transport_credentials.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/transport/status_conversion.h" -#include "src/core/util/json/json.h" -#include "src/core/util/json/json_args.h" -#include "src/core/util/json/json_object_loader.h" -#include "src/core/util/json/json_reader.h" #include "src/core/util/ref_counted_ptr.h" #include "src/core/util/status_helper.h" #include "src/core/util/uri.h" @@ -88,51 +81,16 @@ class JwtTokenFetcherCallCredentials::HttpFetchRequest final self->response_.status))); return; } + // Return token object. absl::string_view body(self->response_.body, self->response_.body_length); - // Parse JWT token based on https://datatracker.ietf.org/doc/html/rfc7519. - // We don't do full verification here, just enough to extract the - // expiration time. - // First, split the 3 '.'-delimited parts. - std::vector parts = absl::StrSplit(body, '.'); - if (parts.size() != 3) { - self->on_done_(absl::UnauthenticatedError("error parsing JWT token")); - return; - } - // Base64-decode the payload. - std::string payload; - if (!absl::WebSafeBase64Unescape(parts[1], &payload)) { - self->on_done_(absl::UnauthenticatedError("error parsing JWT token")); - return; - } - // Parse as JSON. - auto json = JsonParse(payload); - if (!json.ok()) { - self->on_done_(absl::UnauthenticatedError("error parsing JWT token")); + auto expiration_time = GetJwtExpirationTime(body); + if (!expiration_time.ok()) { + self->on_done_(expiration_time.status()); return; } - // Extract "exp" field. - struct ParsedPayload { - uint64_t exp = 0; - - static const JsonLoaderInterface* JsonLoader(const JsonArgs&) { - static const auto kJsonLoader = JsonObjectLoader() - .Field("exp", &ParsedPayload::exp) - .Finish(); - return kJsonLoader; - } - }; - auto parsed_payload = LoadFromJson(*json, JsonArgs(), ""); - if (!parsed_payload.ok()) { - self->on_done_(absl::UnauthenticatedError("error parsing JWT token")); - return; - } - gpr_timespec ts = gpr_time_0(GPR_CLOCK_REALTIME); - ts.tv_sec = parsed_payload->exp; - Timestamp expiration_time = Timestamp::FromTimespecRoundDown(ts); - // Return token object. self->on_done_(MakeRefCounted( Slice::FromCopiedString(absl::StrCat("Bearer ", body)), - expiration_time)); + *expiration_time)); } OrphanablePtr http_request_; diff --git a/deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc b/deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc new file mode 100644 index 00000000000..d694b2ee260 --- /dev/null +++ b/deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc @@ -0,0 +1,86 @@ +// +// Copyright 2025 gRPC authors. +// +// 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. +// + +#include "src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h" + +#include "absl/status/status.h" +#include "absl/strings/str_cat.h" +#include "src/core/credentials/call/jwt_util.h" +#include "src/core/util/load_file.h" + +namespace grpc_core { + +class JwtTokenFileCallCredentials::FileReader final + : public TokenFetcherCredentials::FetchRequest { + public: + FileReader(JwtTokenFileCallCredentials* creds, + absl::AnyInvocable>)> + on_done) + : creds_(creds), on_done_(std::move(on_done)) { + creds->event_engine().Run([self = RefAsSubclass()]() { + ExecCtx exec_ctx; + self->ReadFile(); + }); + } + + void Orphan() override { + // Can't really do anything to cancel in this case. + Unref(); + } + + private: + void ReadFile() { + auto contents = LoadFile(creds_->path_, /*add_null_terminator=*/false); + if (!contents.ok()) { + on_done_(absl::UnavailableError(contents.status().message())); + return; + } + absl::string_view body = contents->as_string_view(); + auto expiration_time = GetJwtExpirationTime(body); + if (!expiration_time.ok()) { + on_done_(expiration_time.status()); + return; + } + on_done_(MakeRefCounted( + Slice::FromCopiedString(absl::StrCat("Bearer ", body)), + *expiration_time)); + } + + JwtTokenFileCallCredentials* creds_; + absl::AnyInvocable>)> + on_done_; +}; + +std::string JwtTokenFileCallCredentials::debug_string() { + return absl::StrCat("JwtTokenFileCallCredentials(", path_, ")"); +} + +UniqueTypeName JwtTokenFileCallCredentials::Type() { + return GRPC_UNIQUE_TYPE_NAME_HERE("JwtTokenFile"); +} + +OrphanablePtr +JwtTokenFileCallCredentials::FetchToken( + Timestamp /*deadline*/, + absl::AnyInvocable< + void(absl::StatusOr>)> + on_done) { + return MakeOrphanable(this, std::move(on_done)); +} + +} // namespace grpc_core diff --git a/deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h b/deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h new file mode 100644 index 00000000000..4de8b911f98 --- /dev/null +++ b/deps/grpc/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h @@ -0,0 +1,74 @@ +// +// Copyright 2025 gRPC authors. +// +// 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. +// + +#ifndef GRPC_SRC_CORE_CREDENTIALS_CALL_JWT_TOKEN_FILE_JWT_TOKEN_FILE_CALL_CREDENTIALS_H +#define GRPC_SRC_CORE_CREDENTIALS_CALL_JWT_TOKEN_FILE_JWT_TOKEN_FILE_CALL_CREDENTIALS_H + +#include +#include + +#include + +#include "absl/functional/any_invocable.h" +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" +#include "src/core/credentials/call/call_credentials.h" +#include "src/core/credentials/call/token_fetcher/token_fetcher_credentials.h" +#include "src/core/util/orphanable.h" +#include "src/core/util/ref_counted_ptr.h" +#include "src/core/util/time.h" +#include "src/core/util/unique_type_name.h" + +namespace grpc_core { + +// JWT token file call credentials. +// See gRFC A97 (https://github.com/grpc/proposal/pull/492). +class JwtTokenFileCallCredentials : public TokenFetcherCredentials { + public: + explicit JwtTokenFileCallCredentials( + absl::string_view path, + std::shared_ptr + event_engine = nullptr) + : TokenFetcherCredentials(std::move(event_engine)), path_(path) {} + + std::string debug_string() override; + + static UniqueTypeName Type(); + + UniqueTypeName type() const override { return Type(); } + + absl::string_view path() const { return path_; } + + private: + class FileReader; + + OrphanablePtr FetchToken( + Timestamp /*deadline*/, + absl::AnyInvocable< + void(absl::StatusOr>)> + on_done) final; + + int cmp_impl(const grpc_call_credentials* other) const override { + // TODO(yashykt): Check if we can do something better here + return QsortCompare(static_cast(this), other); + } + + std::string path_; +}; + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_CREDENTIALS_CALL_JWT_TOKEN_FILE_JWT_TOKEN_FILE_CALL_CREDENTIALS_H diff --git a/deps/grpc/src/core/credentials/call/jwt_util.cc b/deps/grpc/src/core/credentials/call/jwt_util.cc new file mode 100644 index 00000000000..7c5f6fd41e0 --- /dev/null +++ b/deps/grpc/src/core/credentials/call/jwt_util.cc @@ -0,0 +1,70 @@ +// +// Copyright 2025 gRPC authors. +// +// 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. +// + +#include "src/core/credentials/call/jwt_util.h" + +#include + +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/escaping.h" +#include "absl/strings/str_split.h" +#include "src/core/util/json/json.h" +#include "src/core/util/json/json_args.h" +#include "src/core/util/json/json_object_loader.h" +#include "src/core/util/json/json_reader.h" + +namespace grpc_core { + +absl::StatusOr GetJwtExpirationTime(absl::string_view jwt) { + // First, split the 3 '.'-delimited parts. + std::vector parts = absl::StrSplit(jwt, '.'); + if (parts.size() != 3) { + return absl::UnauthenticatedError("error parsing JWT token"); + } + // Base64-decode the payload. + std::string payload; + if (!absl::WebSafeBase64Unescape(parts[1], &payload)) { + return absl::UnauthenticatedError("error parsing JWT token"); + } + // Parse as JSON. + auto json = JsonParse(payload); + if (!json.ok()) { + return absl::UnauthenticatedError("error parsing JWT token"); + } + // Extract "exp" field. + struct ParsedPayload { + uint64_t exp = 0; + + static const JsonLoaderInterface* JsonLoader(const JsonArgs&) { + static const auto kJsonLoader = JsonObjectLoader() + .Field("exp", &ParsedPayload::exp) + .Finish(); + return kJsonLoader; + } + }; + auto parsed_payload = LoadFromJson(*json, JsonArgs(), ""); + if (!parsed_payload.ok()) { + return absl::UnauthenticatedError("error parsing JWT token"); + } + gpr_timespec ts = gpr_time_0(GPR_CLOCK_REALTIME); + ts.tv_sec = parsed_payload->exp; + return Timestamp::FromTimespecRoundDown(ts); +} + +} // namespace grpc_core diff --git a/deps/grpc/src/core/credentials/call/jwt_util.h b/deps/grpc/src/core/credentials/call/jwt_util.h new file mode 100644 index 00000000000..a1a96c20ebc --- /dev/null +++ b/deps/grpc/src/core/credentials/call/jwt_util.h @@ -0,0 +1,32 @@ +// +// Copyright 2025 gRPC authors. +// +// 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. +// + +#ifndef GRPC_SRC_CORE_CREDENTIALS_CALL_JWT_UTIL_H +#define GRPC_SRC_CORE_CREDENTIALS_CALL_JWT_UTIL_H + +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" +#include "src/core/util/time.h" + +namespace grpc_core { + +// Extract the expiration time from a JWT token based on +// https://datatracker.ietf.org/doc/html/rfc7519. +absl::StatusOr GetJwtExpirationTime(absl::string_view jwt); + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_CREDENTIALS_CALL_JWT_UTIL_H diff --git a/deps/grpc/src/core/credentials/transport/channel_creds_registry_init.cc b/deps/grpc/src/core/credentials/transport/channel_creds_registry_init.cc index b5ebf77515a..2ab6c1d949b 100644 --- a/deps/grpc/src/core/credentials/transport/channel_creds_registry_init.cc +++ b/deps/grpc/src/core/credentials/transport/channel_creds_registry_init.cc @@ -57,7 +57,7 @@ class GoogleDefaultChannelCredsFactory : public ChannelCredsFactory<> { RefCountedPtr CreateChannelCreds( RefCountedPtr /*config*/) const override { return RefCountedPtr( - grpc_google_default_credentials_create(nullptr)); + grpc_google_default_credentials_create(nullptr, nullptr)); } private: diff --git a/deps/grpc/src/core/credentials/transport/google_default/google_default_credentials.cc b/deps/grpc/src/core/credentials/transport/google_default/google_default_credentials.cc index ab7f547a8e8..c39da5357da 100644 --- a/deps/grpc/src/core/credentials/transport/google_default/google_default_credentials.cc +++ b/deps/grpc/src/core/credentials/transport/google_default/google_default_credentials.cc @@ -42,6 +42,7 @@ #include "src/core/credentials/call/jwt/json_token.h" #include "src/core/credentials/call/jwt/jwt_credentials.h" #include "src/core/credentials/call/oauth2/oauth2_credentials.h" +#include "src/core/credentials/transport/alts/alts_security_connector.h" #include "src/core/credentials/transport/alts/check_gcp_environment.h" #include "src/core/credentials/transport/transport_credentials.h" #include "src/core/lib/channel/channel_args.h" @@ -338,6 +339,65 @@ static bool metadata_server_available() { return static_cast(g_metadata_server_available); } +// A grpc_call_credentials implementation that uses two +// underlying credentials: one for TLS and one for ALTS. +// The implementation will pick the right credentials based on the auth +// context's GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME property. +class GoogleDefaultCallCredentialsWrapper : public grpc_call_credentials { + public: + GoogleDefaultCallCredentialsWrapper( + grpc_core::RefCountedPtr tls_credentials, + grpc_core::RefCountedPtr alts_credentials) + : tls_credentials_(std::move(tls_credentials)), + alts_credentials_(std::move(alts_credentials)) {}; + + void Orphaned() override { + tls_credentials_.reset(); + alts_credentials_.reset(); + } + + static grpc_core::UniqueTypeName Type() { + static grpc_core::UniqueTypeName::Factory kFactory("Dual"); + return kFactory.Create(); + } + + grpc_core::UniqueTypeName type() const override { return Type(); } + + grpc_core::ArenaPromise> + GetRequestMetadata(grpc_core::ClientMetadataHandle initial_metadata, + const GetRequestMetadataArgs* args) override { + bool use_alts = false; + if (args != nullptr) { + auto auth_context = args->auth_context; + if (auth_context != nullptr && + grpc_auth_context_peer_is_authenticated(auth_context.get()) == 1) { + // This channel is authenticated. + grpc_auth_property_iterator property_it = + grpc_auth_context_find_properties_by_name( + auth_context.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME); + const grpc_auth_property* property = + grpc_auth_property_iterator_next(&property_it); + use_alts = + property != nullptr && + strcmp(property->value, GRPC_ALTS_TRANSPORT_SECURITY_TYPE) == 0; + } + } + return (use_alts ? alts_credentials_ : tls_credentials_) + ->GetRequestMetadata(std::move(initial_metadata), args); + } + + private: + int cmp_impl(const grpc_call_credentials* other) const override { + return QsortCompare(static_cast(this), other); + } + std::string debug_string() override { + return "GoogleDefaultCallCredentialsWrapper"; + } + + grpc_core::RefCountedPtr tls_credentials_; + grpc_core::RefCountedPtr alts_credentials_; +}; + static grpc_core::RefCountedPtr make_default_call_creds( grpc_error_handle* error) { grpc_core::RefCountedPtr call_creds; @@ -373,14 +433,16 @@ static grpc_core::RefCountedPtr make_default_call_creds( } grpc_channel_credentials* grpc_google_default_credentials_create( - grpc_call_credentials* call_credentials) { + grpc_call_credentials* call_creds_for_tls, + grpc_call_credentials* call_creds_for_alts) { grpc_channel_credentials* result = nullptr; - grpc_core::RefCountedPtr call_creds(call_credentials); + grpc_core::RefCountedPtr call_creds( + call_creds_for_tls); grpc_error_handle error; grpc_core::ExecCtx exec_ctx; GRPC_TRACE_LOG(api, INFO) - << "grpc_google_default_credentials_create(" << call_credentials << ")"; + << "grpc_google_default_credentials_create(" << call_creds_for_tls << ")"; if (call_creds == nullptr) { call_creds = make_default_call_creds(&error); @@ -400,6 +462,13 @@ grpc_channel_credentials* grpc_google_default_credentials_create( grpc_core::MakeRefCounted( grpc_core::RefCountedPtr(alts_creds), grpc_core::RefCountedPtr(ssl_creds)); + if (call_creds_for_alts != nullptr) { + grpc_core::RefCountedPtr alts_call_creds( + call_creds_for_alts); + call_creds = + grpc_core::MakeRefCounted( + std::move(call_creds), std::move(alts_call_creds)); + } result = grpc_composite_channel_credentials_create( creds.get(), call_creds.get(), nullptr); CHECK_NE(result, nullptr); @@ -412,7 +481,6 @@ grpc_channel_credentials* grpc_google_default_credentials_create( namespace grpc_core { namespace internal { - void set_gce_tenancy_checker_for_testing(grpc_gce_tenancy_checker checker) { g_gce_tenancy_checker = checker; } diff --git a/deps/grpc/src/core/credentials/transport/ssl/ssl_credentials.cc b/deps/grpc/src/core/credentials/transport/ssl/ssl_credentials.cc index 8ed142c37b7..97b485622a2 100644 --- a/deps/grpc/src/core/credentials/transport/ssl/ssl_credentials.cc +++ b/deps/grpc/src/core/credentials/transport/ssl/ssl_credentials.cc @@ -58,7 +58,6 @@ grpc_ssl_credentials::grpc_ssl_credentials( root_store_ = grpc_core::DefaultSslRootStore::GetRootStore(); } } else { - config_.pem_root_certs = config_.pem_root_certs; root_store_ = nullptr; } diff --git a/deps/grpc/src/core/credentials/transport/tls/load_system_roots_supported.cc b/deps/grpc/src/core/credentials/transport/tls/load_system_roots_supported.cc index bb1b623d3e5..b66b80e375e 100644 --- a/deps/grpc/src/core/credentials/transport/tls/load_system_roots_supported.cc +++ b/deps/grpc/src/core/credentials/transport/tls/load_system_roots_supported.cc @@ -131,6 +131,7 @@ grpc_slice CreateRootCertsBundle(const char* certs_directory) { } else { LOG(ERROR) << "failed to read file: " << roots_filenames[i].path; } + close(file_descriptor); } } bundle_slice = grpc_slice_new(bundle_string, bytes_read, gpr_free); diff --git a/deps/grpc/src/core/credentials/transport/xds/xds_credentials.cc b/deps/grpc/src/core/credentials/transport/xds/xds_credentials.cc index 3e3fb9025b3..306a72df97b 100644 --- a/deps/grpc/src/core/credentials/transport/xds/xds_credentials.cc +++ b/deps/grpc/src/core/credentials/transport/xds/xds_credentials.cc @@ -134,9 +134,6 @@ RefCountedPtr XdsCredentials::create_security_connector( RefCountedPtr call_creds, const char* target_name, ChannelArgs* args) { - // TODO(yashykt): This arg will no longer need to be added after b/173119596 - // is fixed. - *args = args->SetIfUnset(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, target_name); RefCountedPtr security_connector; auto xds_certificate_provider = args->GetObjectRef(); if (xds_certificate_provider != nullptr) { diff --git a/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc b/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc index ef10a1a3a1d..9b649d70f38 100644 --- a/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +++ b/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc @@ -167,14 +167,14 @@ GcpAuthenticationFilter::Create(const ChannelArgs& args, return absl::InvalidArgumentError( "gcp_auth: xds config not found in channel args"); } - // Get existing cache or create new one. - auto cache = filter_args.GetOrCreateState( - filter_config->filter_instance_name, [&]() { - return MakeRefCounted(filter_config->cache_size); - }); - // Make sure size is updated, in case we're reusing a pre-existing - // cache but it has the wrong size. - cache->SetMaxSize(filter_config->cache_size); + // Get cache from blackboard. This must have been populated + // previously by the XdsConfigSelector. + auto cache = filter_args.GetState( + filter_config->filter_instance_name); + if (cache == nullptr) { + return absl::InvalidArgumentError( + "gcp_auth: cache object not found in filter state"); + } // Instantiate filter. return std::unique_ptr( new GcpAuthenticationFilter(std::move(service_config), filter_config, diff --git a/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h b/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h index cac2ae7ac77..8d5a71eefbb 100644 --- a/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +++ b/deps/grpc/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h @@ -42,6 +42,22 @@ namespace grpc_core { class GcpAuthenticationFilter : public ImplementChannelFilter { public: + class CallCredentialsCache : public Blackboard::Entry { + public: + explicit CallCredentialsCache(size_t max_size) : cache_(max_size) {} + + static UniqueTypeName Type(); + + void SetMaxSize(size_t max_size); + + RefCountedPtr Get(const std::string& audience); + + private: + Mutex mu_; + LruCache> + cache_ ABSL_GUARDED_BY(&mu_); + }; + static const grpc_channel_filter kFilter; static absl::string_view TypeName() { return "gcp_authentication_filter"; } @@ -62,22 +78,6 @@ class GcpAuthenticationFilter }; private: - class CallCredentialsCache : public Blackboard::Entry { - public: - explicit CallCredentialsCache(size_t max_size) : cache_(max_size) {} - - static UniqueTypeName Type(); - - void SetMaxSize(size_t max_size); - - RefCountedPtr Get(const std::string& audience); - - private: - Mutex mu_; - LruCache> - cache_ ABSL_GUARDED_BY(&mu_); - }; - GcpAuthenticationFilter( RefCountedPtr service_config, const GcpAuthenticationParsedConfig::Config* filter_config, diff --git a/deps/grpc/src/core/ext/filters/http/client_authority_filter.cc b/deps/grpc/src/core/ext/filters/http/client_authority_filter.cc index 7a8febaff59..42ec6e40021 100644 --- a/deps/grpc/src/core/ext/filters/http/client_authority_filter.cc +++ b/deps/grpc/src/core/ext/filters/http/client_authority_filter.cc @@ -73,13 +73,11 @@ void RegisterClientAuthorityFilter(CoreConfiguration::Builder* builder) { builder->channel_init() ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) .If(NeedsClientAuthorityFilter) - .Before() - .Before(); + .Before(); builder->channel_init() ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) .If(NeedsClientAuthorityFilter) - .Before() - .Before(); + .Before(); } } // namespace grpc_core diff --git a/deps/grpc/src/core/ext/filters/http/message_compress/compression_filter.h b/deps/grpc/src/core/ext/filters/http/message_compress/compression_filter.h index ed75c859d18..6c32eaccf86 100644 --- a/deps/grpc/src/core/ext/filters/http/message_compress/compression_filter.h +++ b/deps/grpc/src/core/ext/filters/http/message_compress/compression_filter.h @@ -24,11 +24,13 @@ #include #include +#include #include #include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "src/core/call/metadata_batch.h" +#include "src/core/channelz/property_list.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_fwd.h" #include "src/core/lib/channel/promise_based_filter.h" @@ -91,18 +93,15 @@ class ChannelCompression { bool is_client, MessageHandle message, DecompressArgs args, CallTracerInterface* call_tracer) const; - Json::Object ToJsonObject() const { - Json::Object object; - if (max_recv_size_.has_value()) { - object["maxRecvSize"] = Json::FromNumber(*max_recv_size_); - } - object["defaultCompressionAlgorithm"] = Json::FromString( - CompressionAlgorithmAsString(default_compression_algorithm_)); - object["enabledCompressionAlgorithms"] = Json::FromString( - std::string(enabled_compression_algorithms_.ToString())); - object["enableCompression"] = Json::FromBool(enable_compression_); - object["enableDecompression"] = Json::FromBool(enable_decompression_); - return object; + channelz::PropertyList ChannelzProperties() const { + return channelz::PropertyList() + .Set("max_recv_size", max_recv_size_) + .Set("default_compression_algorithm", + CompressionAlgorithmAsString(default_compression_algorithm_)) + .Set("enabled_compression_algorithms", + enabled_compression_algorithms_.ToString()) + .Set("enable_compression", enable_compression_) + .Set("enable_decompression", enable_decompression_); } private: @@ -132,12 +131,14 @@ class ClientCompressionFilter final explicit ClientCompressionFilter(const ChannelArgs& args) : channelz::DataSource(args.GetObjectRef()), - compression_engine_(args) {} - ~ClientCompressionFilter() override { ResetDataSource(); } + compression_engine_(args) { + SourceConstructed(); + } + ~ClientCompressionFilter() override { SourceDestructing(); } - void AddData(channelz::DataSink& sink) override { - sink.AddAdditionalInfo("clientCompressionFilter", - compression_engine_.ToJsonObject()); + void AddData(channelz::DataSink sink) override { + sink.AddData("clientCompressionFilter", + compression_engine_.ChannelzProperties()); } // Construct a promise for one call. @@ -182,12 +183,14 @@ class ServerCompressionFilter final explicit ServerCompressionFilter(const ChannelArgs& args) : channelz::DataSource(args.GetObjectRef()), - compression_engine_(args) {} - ~ServerCompressionFilter() override { ResetDataSource(); } + compression_engine_(args) { + SourceConstructed(); + } + ~ServerCompressionFilter() override { SourceDestructing(); } - void AddData(channelz::DataSink& sink) override { - sink.AddAdditionalInfo("serverCompressionFilter", - compression_engine_.ToJsonObject()); + void AddData(channelz::DataSink sink) override { + sink.AddData("serverCompressionFilter", + compression_engine_.ChannelzProperties()); } // Construct a promise for one call. diff --git a/deps/grpc/src/core/ext/filters/http/server/http_server_filter.h b/deps/grpc/src/core/ext/filters/http/server/http_server_filter.h index 2fb462c1e71..a287515fd5f 100644 --- a/deps/grpc/src/core/ext/filters/http/server/http_server_filter.h +++ b/deps/grpc/src/core/ext/filters/http/server/http_server_filter.h @@ -22,17 +22,16 @@ #include #include "absl/status/statusor.h" +#include "src/core/channelz/property_list.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_fwd.h" #include "src/core/lib/channel/promise_based_filter.h" -#include "src/core/lib/promise/arena_promise.h" -#include "src/core/lib/transport/transport.h" namespace grpc_core { // Processes metadata on the server side for HTTP2 transports -class HttpServerFilter : public ImplementChannelFilter, - public channelz::DataSource { +class HttpServerFilter final : public ImplementChannelFilter, + public channelz::DataSource { public: static const grpc_channel_filter kFilter; @@ -45,14 +44,16 @@ class HttpServerFilter : public ImplementChannelFilter, bool allow_put_requests) : channelz::DataSource(args.GetObjectRef()), surface_user_agent_(surface_user_agent), - allow_put_requests_(allow_put_requests) {} - ~HttpServerFilter() override { ResetDataSource(); } + allow_put_requests_(allow_put_requests) { + SourceConstructed(); + } + ~HttpServerFilter() override { SourceDestructing(); } - void AddData(channelz::DataSink& sink) override { - Json::Object object; - object["surfaceUserAgent"] = Json::FromBool(surface_user_agent_); - object["allowPutRequests"] = Json::FromBool(allow_put_requests_); - sink.AddAdditionalInfo("httpServerFilter", object); + void AddData(channelz::DataSink sink) override { + sink.AddData("httpServerFilter", + channelz::PropertyList() + .Set("surface_user_agent", surface_user_agent_) + .Set("allow_put_requests", allow_put_requests_)); } class Call { diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc b/deps/grpc/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc index 6ee26fdf2d3..ee3a7fbe70c 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc @@ -100,6 +100,10 @@ absl::StatusOr ResultFromHandshake( endpoint = grpc_event_engine::experimental:: grpc_take_wrapped_event_engine_endpoint( (*result)->endpoint.release()); + if (endpoint == nullptr) { + LOG(ERROR) << "Failed to take endpoint."; + return absl::InternalError("Failed to take endpoint."); + } auto* chaotic_good_ext = grpc_event_engine::experimental::QueryExtension< grpc_event_engine::experimental::ChaoticGoodExtension>(endpoint.get()); if (chaotic_good_ext != nullptr) { diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.cc b/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.cc index 17f7607337c..32ba8ed8527 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.cc @@ -120,9 +120,10 @@ void ChaoticGoodClientTransport::StreamDispatch::DispatchFrame( auto stream = LookupStream(incoming_frame.header().stream_id); if (stream == nullptr) return; auto dispatcher = stream->frame_dispatch_serializer; - dispatcher->Spawn([stream = std::move(stream), + dispatcher->Spawn([stream, incoming_frame = std::move(incoming_frame)]() mutable { - return Map(stream->call.CancelIfFails(TrySeq( + auto& call = stream->call; + return Map(call.CancelIfFails(TrySeq( incoming_frame.Payload(), [stream = std::move(stream)](Frame frame) mutable { auto& call = stream->call; @@ -194,7 +195,7 @@ uint32_t ChaoticGoodClientTransport::StreamDispatch::MakeStream( << " done: cancelled=" << cancelled; if (cancelled) { self->outgoing_frames_.UnbufferedImmediateSend( - UntracedOutgoingFrame(CancelFrame{stream_id})); + UntracedOutgoingFrame(CancelFrame{stream_id}), 1); } MutexLock lock(&self->mu_); self->stream_map_.erase(stream_id); @@ -221,7 +222,8 @@ void ChaoticGoodClientTransport::StreamDispatch::StopConnectivityWatch( ChaoticGoodClientTransport::ChaoticGoodClientTransport( const ChannelArgs& args, OrphanablePtr frame_transport, MessageChunker message_chunker) - : ctx_(frame_transport->ctx()), + : channelz::DataSource(frame_transport->ctx()->socket_node), + ctx_(frame_transport->ctx()), allocator_(args.GetObject() ->memory_quota() ->CreateMemoryAllocator("chaotic-good")), @@ -232,17 +234,21 @@ ChaoticGoodClientTransport::ChaoticGoodClientTransport( party_arena->SetContext( ctx_->event_engine.get()); party_ = Party::Make(std::move(party_arena)); - MpscReceiver outgoing_frames{8}; + MpscReceiver outgoing_frames{256 * 1024 * 1024}; outgoing_frames_ = outgoing_frames.MakeSender(); stream_dispatch_ = MakeRefCounted(outgoing_frames.MakeSender()); frame_transport_->Start(party_.get(), std::move(outgoing_frames), stream_dispatch_); + SourceConstructed(); } -ChaoticGoodClientTransport::~ChaoticGoodClientTransport() { party_.reset(); } +ChaoticGoodClientTransport::~ChaoticGoodClientTransport() { + DCHECK(party_.get() == nullptr); +} void ChaoticGoodClientTransport::Orphan() { + SourceDestructing(); stream_dispatch_->OnFrameTransportClosed( absl::UnavailableError("Transport closed")); party_.reset(); @@ -250,6 +256,11 @@ void ChaoticGoodClientTransport::Orphan() { Unref(); } +void ChaoticGoodClientTransport::AddData(channelz::DataSink sink) { + // TODO(ctiller): add calls in stream dispatch + party_->ExportToChannelz("transport_party", sink); +} + auto ChaoticGoodClientTransport::CallOutboundLoop(uint32_t stream_id, CallHandler call_handler) { CallTracerInterface* const tracer = @@ -260,7 +271,9 @@ auto ChaoticGoodClientTransport::CallOutboundLoop(uint32_t stream_id, } auto send_fragment = [this, call_tracer, stream_id](auto frame) mutable { frame.stream_id = stream_id; - return outgoing_frames_.Send(OutgoingFrame{std::move(frame), call_tracer}); + auto tokens = FrameMpscTokens(frame); + return outgoing_frames_.Send(OutgoingFrame{std::move(frame), call_tracer}, + tokens); }; auto send_message = [this, stream_id, call_tracer, message_chunker = @@ -317,8 +330,10 @@ void ChaoticGoodClientTransport::StartCall(CallHandler call_handler) { GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: Send cancel"; if (!self->outgoing_frames_ - .UnbufferedImmediateSend(UntracedOutgoingFrame( - CancelFrame{stream_id})) + .UnbufferedImmediateSend( + UntracedOutgoingFrame( + CancelFrame{stream_id}), + 1) .ok()) { GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: Send cancel failed"; diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.h b/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.h index 57e7feccb96..61e3613885e 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/client_transport.h @@ -66,7 +66,8 @@ namespace grpc_core { namespace chaotic_good { -class ChaoticGoodClientTransport final : public ClientTransport { +class ChaoticGoodClientTransport final : public ClientTransport, + public channelz::DataSource { public: ChaoticGoodClientTransport(const ChannelArgs& args, OrphanablePtr frame_transport, @@ -84,6 +85,7 @@ class ChaoticGoodClientTransport final : public ClientTransport { RefCountedPtr GetSocketNode() const override { return ctx_->socket_node; } + void AddData(channelz::DataSink sink) override; void StartCall(CallHandler call_handler) override; diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/config.h b/deps/grpc/src/core/ext/transport/chaotic_good/config.h index 7b8c82ba21e..997524bae92 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/config.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/config.h @@ -35,6 +35,8 @@ namespace chaotic_good { "grpc.chaotic_good.max_send_chunk_size" #define GRPC_ARG_CHAOTIC_GOOD_INLINED_PAYLOAD_SIZE_THRESHOLD \ "grpc.chaotic_good.inlined_payload_size_threshold" +#define GRPC_ARG_CHAOTIC_GOOD_SCHEDULER_CONFIG \ + "grpc.chaotic_good.scheduler_config" // Transport configuration. // Most of our configuration is derived from channel args, and then exchanged @@ -56,6 +58,9 @@ class Config { max_send_chunk_size_ = std::max( 0, channel_args.GetInt(GRPC_ARG_CHAOTIC_GOOD_MAX_SEND_CHUNK_SIZE) .value_or(max_send_chunk_size_)); + scheduler_config_ = + channel_args.GetString(GRPC_ARG_CHAOTIC_GOOD_SCHEDULER_CONFIG) + .value_or("spanrr"); if (max_recv_chunk_size_ == 0 || max_send_chunk_size_ == 0) { max_recv_chunk_size_ = 0; max_send_chunk_size_ = 0; @@ -148,6 +153,7 @@ class Config { options.encode_alignment = encode_alignment_; options.decode_alignment = decode_alignment_; options.inlined_payload_size_threshold = inline_payload_size_threshold_; + options.scheduler_config = scheduler_config_; return options; } @@ -218,6 +224,7 @@ class Config { uint32_t max_send_chunk_size_ = 1024 * 1024; uint32_t max_recv_chunk_size_ = 1024 * 1024; uint32_t inline_payload_size_threshold_ = 8 * 1024; + std::string scheduler_config_; std::vector pending_data_endpoints_; absl::flat_hash_set supported_features_; diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/control_endpoint.h b/deps/grpc/src/core/ext/transport/chaotic_good/control_endpoint.h index 943c830760d..cdb1211403a 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/control_endpoint.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/control_endpoint.h @@ -93,7 +93,10 @@ class ControlEndpoint { // Write some data to the control endpoint; returns a promise that resolves // to Empty{} -- it's not possible to see errors from this api. - auto Write(SliceBuffer&& bytes) { return buffer_->Queue(std::move(bytes)); } + auto Write(SliceBuffer&& bytes) { + return GRPC_LATENT_SEE_PROMISE("CtlEndpointEnqueueWrite", + buffer_->Queue(std::move(bytes))); + } // Read operations are simply passthroughs to the underlying promise endpoint. auto ReadSlice(size_t length) { diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.cc b/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.cc index 34fd2485a80..fe4e2c4803d 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.cc @@ -14,13 +14,23 @@ #include "src/core/ext/transport/chaotic_good/data_endpoints.h" +#include + #include #include #include #include #include +#include +#include #include "absl/cleanup/cleanup.h" +#include "absl/container/inlined_vector.h" +#include "absl/log/log.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" +#include "absl/time/time.h" +#include "src/core/channelz/property_list.h" #include "src/core/ext/transport/chaotic_good/tcp_frame_header.h" #include "src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h" #include "src/core/ext/transport/chaotic_good/transport_context.h" @@ -30,10 +40,14 @@ #include "src/core/lib/event_engine/tcp_socket_utils.h" #include "src/core/lib/promise/loop.h" #include "src/core/lib/promise/map.h" +#include "src/core/lib/promise/race.h" #include "src/core/lib/promise/try_seq.h" #include "src/core/lib/transport/transport_framing_endpoint_extension.h" #include "src/core/telemetry/default_tcp_tracer.h" #include "src/core/util/dump_args.h" +#include "src/core/util/latent_see.h" +#include "src/core/util/ref_counted.h" +#include "src/core/util/shared_bit_gen.h" #include "src/core/util/string.h" namespace grpc_core { @@ -48,404 +62,482 @@ const uint64_t kSecurityFramePayloadTag = 0; /////////////////////////////////////////////////////////////////////////////// // SendRate -void SendRate::StartSend(uint64_t current_time, uint64_t send_size) { - CHECK_NE(current_time, 0u); - send_start_time_ = current_time; - send_size_ = send_size; -} - -void SendRate::MaybeCompleteSend(uint64_t current_time) { - if (send_start_time_ == 0) return; - if (current_time > send_start_time_) { - const double rate = static_cast(send_size_) / - static_cast(current_time - send_start_time_); - // Adjust send rate based on observations. - if (current_rate_ > 0) { - current_rate_ = 0.9 * current_rate_ + 0.1 * rate; +void SendRate::SetNetworkMetrics(const std::optional& network_send, + const NetworkMetrics& metrics) { + bool updated = false; + if (metrics.rtt_usec.has_value()) { + CHECK_GE(*metrics.rtt_usec, 0u); + rtt_usec_ = *metrics.rtt_usec; + updated = true; + } + if (metrics.bytes_per_nanosecond.has_value()) { + if (metrics.bytes_per_nanosecond < 0) { + LOG_EVERY_N_SEC(ERROR, 10) + << "Negative bytes per nanosecond: " << *metrics.bytes_per_nanosecond; + } else if (std::isnan(*metrics.bytes_per_nanosecond)) { + LOG_EVERY_N_SEC(ERROR, 10) + << "NaN bytes per nanosecond: " << *metrics.bytes_per_nanosecond; } else { - current_rate_ = rate; + current_rate_ = *metrics.bytes_per_nanosecond; } + updated = true; } - send_start_time_ = 0; -} - -void SendRate::SetCurrentRate(double bytes_per_nanosecond) { - CHECK_GE(bytes_per_nanosecond, 0.0); - current_rate_ = bytes_per_nanosecond; - last_rate_measurement_ = Timestamp::Now(); + if (network_send.has_value() && + network_send->start_time > last_send_started_time_) { + last_send_started_time_ = network_send->start_time; + last_send_bytes_outstanding_ = network_send->bytes; + updated = true; + } + if (updated) last_rate_measurement_ = Timestamp::Now(); } bool SendRate::IsRateMeasurementStale() const { return Timestamp::Now() - last_rate_measurement_ > Duration::Seconds(1); } -LbDecision SendRate::GetLbDecision(uint64_t current_time, size_t bytes) { - LbDecision decision; - decision.bytes = bytes; - if (send_start_time_ != 0) { - decision.current_send = { - send_size_, - static_cast(current_time - send_start_time_) * 1e-9, - }; - } - decision.current_rate = current_rate_; - if (current_rate_ <= 0 || IsRateMeasurementStale()) { - decision.delivery_time = 0.0; - return decision; - } +SendRate::DeliveryData SendRate::GetDeliveryData(uint64_t current_time) const { // start time relative to the current time for this send double start_time = 0.0; - if (send_start_time_ != 0) { + if (last_send_started_time_ != 0 && current_rate_ > 0) { // Use integer subtraction to avoid rounding errors, getting everything // with a zero base of 'now' to maximize precision. // Since we have uint64_ts and want a signed double result we need to // care about argument ordering to get a valid result. const double send_start_time_relative_to_now = - current_time > send_start_time_ - ? -static_cast(current_time - send_start_time_) - : static_cast(send_start_time_ - current_time); + current_time > last_send_started_time_ + ? -static_cast(current_time - last_send_started_time_) + : static_cast(last_send_started_time_ - current_time); const double predicted_end_time = - send_start_time_relative_to_now + current_rate_ * send_size_; + send_start_time_relative_to_now + + last_send_bytes_outstanding_ / current_rate_; if (predicted_end_time > start_time) start_time = predicted_end_time; } - decision.delivery_time = (start_time + bytes / current_rate_) * 1e-9; - return decision; + if (current_rate_ <= 0) { + return DeliveryData{(start_time + rtt_usec_ * 500.0) * 1e-9, 1e14}; + } else { + return DeliveryData{(start_time + rtt_usec_ * 500.0) * 1e-9, + current_rate_ * 1e9}; + } } -void SendRate::AddData(Json::Object& obj) const { - if (send_start_time_ != 0) { - obj["send_start_time"] = Json::FromNumber(send_start_time_); - obj["send_size"] = Json::FromNumber(send_size_); +channelz::PropertyList SendRate::ChannelzProperties() const { + channelz::PropertyList obj; + if (last_send_started_time_ != 0) { + obj.Set("send_start_time", last_send_started_time_) + .Set("send_size", last_send_bytes_outstanding_); } - obj["current_rate"] = Json::FromNumber(current_rate_); - obj["rate_measurement_age"] = - Json::FromNumber((Timestamp::Now() - last_rate_measurement_).millis()); + return obj.Set("current_rate", current_rate_) + .Set("rtt", rtt_usec_) + .Set("last_rate_measurement", last_rate_measurement_); } /////////////////////////////////////////////////////////////////////////////// -// OutputBuffer - -LbDecision OutputBuffer::GetLbDecision(uint64_t current_time, size_t bytes) { - LbDecision decision = - send_rate_.GetLbDecision(current_time, pending_.Length() + bytes); - CHECK(decision.delivery_time.has_value()); - // If there's already data queued and we claim immediate sending (eg new - // connection) OR if the send would take >300ms... wait for a bit. - if (pending_.Length() != 0) { - if (*decision.delivery_time <= 0.0 || *decision.delivery_time > 0.3) { - decision.delivery_time = std::nullopt; +// OutputBuffers + +void OutputBuffers::Reader::EndReadNext() { + mu_.Lock(); + reading_ = false; + if (GPR_UNLIKELY(!frames_.empty())) { + // Cancellation -- we need to return the frames to the output buffer. + // This probably messes up ordering, which messes up fairness (ordering has + // no semantic meaning here), but this edge puts us far from + // critical path anyway. + auto frames = std::move(frames_); + frames_.clear(); + mu_.Unlock(); + for (auto& frame : frames) { + output_buffers_->Write(frame.payload_tag, std::move(frame.frame)); } + } else { + mu_.Unlock(); } - return decision; -} - -void OutputBuffer::MaybeCompleteSend(uint64_t current_time) { - send_rate_.MaybeCompleteSend(current_time); } -NextWrite OutputBuffer::TakePendingAndStartWrite(uint64_t current_time) { - send_rate_.StartSend(current_time, pending_.Length()); - bool trace = false; - if (send_rate_.IsRateMeasurementStale()) { - send_rate_.PerformRateProbe(); - trace = true; +Poll> +OutputBuffers::Reader::PollReadNext() { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::PollReadNext"); + mu_.Lock(); + while (true) { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::PollReadNext::loop"); + if (frames_.empty()) { + if (!reading_) { + reading_ = true; + output_buffers_->WakeupScheduler(); + } + waker_ = GetContext()->MakeNonOwningWaker(); + mu_.Unlock(); + return Pending{}; + } + DCHECK(!reading_); + auto frames = std::move(frames_); + frames_.clear(); + mu_.Unlock(); + return std::move(frames); } - NextWrite next_write; - next_write.bytes = std::move(pending_); - next_write.trace = trace; - pending_.Clear(); - return next_write; } -void OutputBuffer::AddData(Json::Object& obj) const { - obj["have_flush_waker"] = Json::FromBool(!flush_waker_.is_unwakeable()); - obj["pending_bytes"] = Json::FromNumber(pending_.Length()); - send_rate_.AddData(obj); +void OutputBuffers::Reader::SetNetworkMetrics( + const std::optional& network_send, + const SendRate::NetworkMetrics& metrics) { + mu_.Lock(); + send_rate_.SetNetworkMetrics(network_send, metrics); + mu_.Unlock(); + output_buffers_->WakeupScheduler(); } -/////////////////////////////////////////////////////////////////////////////// -// OutputBuffers - -void OutputBuffers::WriteSecurityFrame(uint32_t connection_id, - SliceBuffer output_buffer) { - Waker waker; - auto cleanup = absl::MakeCleanup([&waker]() { waker.Wakeup(); }); - MutexLock lock(&mu_); - auto& buffer = buffers_[connection_id]; - if (!buffer.has_value()) return; - waker = buffer->TakeWaker(); - SliceBuffer& output = buffer->pending(); - CHECK_LT(output_buffer.Length(), std::numeric_limits::max()); - const uint32_t payload_length = static_cast(output_buffer.Length()); - TcpDataFrameHeader hdr{kSecurityFramePayloadTag, 0, payload_length}; - auto header_padding = DataConnectionPadding( - TcpDataFrameHeader::kFrameHeaderSize, encode_alignment_); - MutableSlice header_slice = MutableSlice::CreateUninitialized( - TcpDataFrameHeader::kFrameHeaderSize + header_padding); - hdr.Serialize(header_slice.data()); - if (header_padding > 0) { - memset(header_slice.data() + TcpDataFrameHeader::kFrameHeaderSize, 0, - header_padding); - } - output.AppendIndexed(Slice(std::move(header_slice))); - const auto payload_padding = - DataConnectionPadding(output_buffer.Length(), encode_alignment_); - output.TakeAndAppend(output_buffer); - if (payload_padding > 0) { - auto slice = MutableSlice::CreateUninitialized(payload_padding); - memset(slice.data(), 0, payload_padding); - output.AppendIndexed(Slice(std::move(slice))); - } - CHECK_EQ(output.Length() % encode_alignment_, 0u) << GRPC_DUMP_ARGS( - output.Length(), encode_alignment_, header_padding, payload_padding); -} - -Poll OutputBuffers::PollWrite(uint64_t payload_tag, uint64_t send_time, - SliceBuffer& output_buffer, - std::shared_ptr&) { - Waker waker; - auto cleanup = absl::MakeCleanup([&waker]() { waker.Wakeup(); }); - const uint32_t length = output_buffer.Length(); - const size_t write_size = - TcpDataFrameHeader::kFrameHeaderSize + - DataConnectionPadding(TcpDataFrameHeader::kFrameHeaderSize, - encode_alignment_) + - length + DataConnectionPadding(length, encode_alignment_); - CHECK_EQ(write_size % encode_alignment_, 0u) - << GRPC_DUMP_ARGS(write_size, length, encode_alignment_); +channelz::PropertyList OutputBuffers::Reader::ChannelzProperties() { MutexLock lock(&mu_); - size_t best_endpoint = std::numeric_limits::max(); - double earliest_delivery = std::numeric_limits::max(); - for (size_t i = 0; i < buffers_.size(); ++i) { - if (!buffers_[i].has_value()) continue; - auto decision = buffers_[i]->GetLbDecision(send_time, write_size); - if (!decision.delivery_time.has_value()) continue; - if (*decision.delivery_time < earliest_delivery) { - earliest_delivery = *decision.delivery_time; - best_endpoint = i; - } - } - if (best_endpoint == std::numeric_limits::max()) { - GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: No data endpoint ready for " << length - << " bytes on queue " << this; - ztrace_collector_->Append(NoEndpointForWriteTrace{length, payload_tag}); - write_waker_ = GetContext()->MakeNonOwningWaker(); - return Pending{}; - } - TcpDataFrameHeader hdr{payload_tag, send_time, length}; - ztrace_collector_->Append( - [this, &hdr, send_time, best_endpoint, write_size]() { - std::vector> lb_decisions; + return channelz::PropertyList() + .Set("reading", reading_) + .Merge(send_rate_.ChannelzProperties()) + .Set("queued_frames", [this]() -> std::optional { mu_.AssertHeld(); - for (size_t i = 0; i < buffers_.size(); ++i) { - if (!buffers_[i].has_value()) { - lb_decisions.emplace_back(std::nullopt); - continue; - } - lb_decisions.emplace_back( - buffers_[i]->GetLbDecision(send_time, write_size)); + if (frames_.empty()) return std::nullopt; + channelz::PropertyTable frames; + for (auto& frame : frames_) { + frames.AppendRow( + channelz::PropertyList() + .Set("payload_tag", frame.payload_tag) + .Set("header", absl::ConvertVariantTo( + frame.frame->payload) + .ToString()) + .Set("mpsc_tokens", frame.frame.tokens())); } - return WriteLargeFrameHeaderTrace{hdr, best_endpoint, - std::move(lb_decisions)}; - }); - GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: Queue " << length << " data in " << write_size - << "b wire bytes onto endpoint " << best_endpoint << " queue " << this; - auto& buffer = buffers_[best_endpoint]; - waker = buffer->TakeWaker(); - SliceBuffer& output = buffer->pending(); - CHECK_EQ(output.Length() % encode_alignment_, 0u) - << GRPC_DUMP_ARGS(output.Length(), encode_alignment_); - const auto header_padding = DataConnectionPadding( - TcpDataFrameHeader::kFrameHeaderSize, encode_alignment_); - MutableSlice header_slice = MutableSlice::CreateUninitialized( - TcpDataFrameHeader::kFrameHeaderSize + header_padding); - TcpDataFrameHeader{payload_tag, send_time, length}.Serialize( - header_slice.data()); - if (header_padding > 0) { - memset(header_slice.data() + TcpDataFrameHeader::kFrameHeaderSize, 0, - header_padding); - } - output.AppendIndexed(Slice(std::move(header_slice))); - const auto payload_padding = - DataConnectionPadding(output_buffer.Length(), encode_alignment_); - output.TakeAndAppend(output_buffer); - // Add padding for output buffer - if (payload_padding > 0) { - auto slice = MutableSlice::CreateUninitialized(payload_padding); - memset(slice.data(), 0, payload_padding); - output.AppendIndexed(Slice(std::move(slice))); - } - CHECK_EQ(output.Length() % encode_alignment_, 0u) << GRPC_DUMP_ARGS( - output.Length(), encode_alignment_, header_padding, payload_padding); - return Empty{}; -} - -Poll OutputBuffers::PollNext(uint32_t connection_id) { - Waker waker; - auto cleanup = absl::MakeCleanup([&waker]() { waker.Wakeup(); }); - MutexLock lock(&mu_); - const auto current_time = clock_->Now(); - auto& buffer = buffers_[connection_id]; - CHECK(buffer.has_value()); - buffer->MaybeCompleteSend(current_time); - if (buffer->HavePending()) { - waker = std::move(write_waker_); - return buffer->TakePendingAndStartWrite(current_time); - } - buffer->SetWaker(); - return Pending{}; + return frames; + }()); } -void OutputBuffers::AddEndpoint(uint32_t connection_id) { - Waker waker; - auto cleanup = absl::MakeCleanup([&waker]() { waker.Wakeup(); }); - MutexLock lock(&mu_); - if (buffers_.size() < connection_id + 1) { - buffers_.resize(connection_id + 1); +void OutputBuffers::AddData(channelz::DataSink sink) { + sink.AddData( + "output_buffers", + channelz::PropertyList() + .Set("num_readers", num_readers_.load(std::memory_order_relaxed)) + .Set("encode_alignment", encode_alignment_) + .Set("scheduling_state", + scheduling_state_.load(std::memory_order_relaxed)) + .Set("scheduler", scheduler_->Config())); + scheduling_party_->ExportToChannelz("scheduling_party", sink); +} + +RefCountedPtr OutputBuffers::MakeReader(uint32_t id) { + MutexLock lock(&mu_reader_data_); + if (readers_.size() <= id) { + readers_.resize(id + 1); } - CHECK(!buffers_[connection_id].has_value()) << GRPC_DUMP_ARGS(connection_id); - buffers_[connection_id].emplace(); - waker = std::move(write_waker_); - ready_endpoints_.fetch_add(1, std::memory_order_relaxed); + RefCountedPtr& reader = readers_[id]; + DCHECK_EQ(reader.get(), nullptr); + reader = MakeRefCounted(Ref(), id); + num_readers_.fetch_add(1, std::memory_order_relaxed); + return reader; } -void OutputBuffers::UpdateSendRate(uint32_t connection_id, - double bytes_per_nanosecond) { - MutexLock lock(&mu_); - auto& buffer = buffers_[connection_id]; - if (!buffer.has_value()) return; - buffer->UpdateSendRate(bytes_per_nanosecond); +void OutputBuffers::DestroyReader(uint32_t id) { + mu_reader_data_.Lock(); + RefCountedPtr reader = std::move(readers_[id]); + DCHECK_NE(reader.get(), nullptr); + mu_reader_data_.Unlock(); + reader->mu_.Lock(); + reader->reading_ = false; + auto waker = std::move(reader->waker_); + reader->mu_.Unlock(); + waker.Wakeup(); + num_readers_.fetch_sub(1, std::memory_order_relaxed); } -void OutputBuffers::AddData(channelz::DataSink& sink) { - Json::Object data; - MutexLock lock(&mu_); - data["ready_endpoints"] = - Json::FromNumber(ready_endpoints_.load(std::memory_order_relaxed)); - data["have_write_waker"] = Json::FromBool(!write_waker_.is_unwakeable()); - Json::Array buffers; - for (const auto& buffer : buffers_) { - Json::Object obj; - if (!buffer.has_value()) { - obj["write_state"] = Json::FromString("closed"); - } else { - obj["write_state"] = Json::FromString("open"); - buffer->AddData(obj); +void OutputBuffers::WakeupScheduler() { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::WakeupScheduler"); + auto state = scheduling_state_.load(std::memory_order_acquire); + // CAS's here-in need to be acq-rel, so that we get an acquire on failure (at + // which point we may be loading a Waker pointer). + while (true) { + switch (state) { + case kSchedulingProcessing: + if (!scheduling_state_.compare_exchange_weak( + state, kSchedulingWorkAvailable, std::memory_order_acq_rel)) { + continue; + } + return; + case kSchedulingWorkAvailable: + return; + default: { + // Idle: value is a pointer to a waker. + Waker* waker = reinterpret_cast(state); + if (!scheduling_state_.compare_exchange_weak( + state, kSchedulingWorkAvailable, std::memory_order_acq_rel)) { + continue; + } + waker->Wakeup(); + delete waker; + return; + } } - buffers.emplace_back(Json::FromObject(std::move(obj))); + LOG(FATAL) << "Unreachable state: " << state; } - data["buffers"] = Json::FromArray(std::move(buffers)); - sink.AddAdditionalInfo("outputBuffers", std::move(data)); } -/////////////////////////////////////////////////////////////////////////////// -// InputQueues +Poll OutputBuffers::SchedulerPollForWork() { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::SchedulerPollForWork"); + auto state = scheduling_state_.load(std::memory_order_acquire); + while (true) { + switch (state) { + case kSchedulingProcessing: { + // We were processing, now we're done. + Waker* waker = new Waker(GetContext()->MakeNonOwningWaker()); + // CAS acq rel to make sure we acquire waker pointers on failure. + if (!scheduling_state_.compare_exchange_weak( + state, reinterpret_cast(waker), + std::memory_order_acq_rel)) { + delete waker; + continue; + } + return Pending{}; + } + case kSchedulingWorkAvailable: { + // No pointer exchange here, no need for barriers. + scheduling_state_.store(kSchedulingProcessing, + std::memory_order_relaxed); + return Empty{}; + } + default: + return Pending{}; + } + LOG(FATAL) << "Unreachable state: " << state; + } +} -InputQueue::ReadTicket InputQueue::Read(uint64_t payload_tag) { +void OutputBuffers::Schedule() { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::Schedule"); + auto* first_message = frames_queue_.Peek(); + if (first_message == nullptr) return; + std::vector scheduling_data; + uint64_t queued_tokens = 0; + { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::Schedule::CollectData1"); + MutexLock lock(&mu_reader_data_); + scheduling_data.reserve(readers_.size()); + for (const auto& reader : readers_) { + scheduling_data.emplace_back(reader); + } + queued_tokens = mpsc_probe_.QueuedTokens(); + } + // Note that we use the number of queued tokens as the scheduling metric, + // not number of bytes on the wire. + // When we enqueue to the mpsc we don't know the wire size, since we don't + // know that the bytes are going out over a TCP collective, or whether they'll + // hit data endpoints or be inlined on a control channel. + scheduler_->NewStep(queued_tokens, first_message->frame.tokens()); + const auto now = clock_->Now(); + bool any_readers = false; { - MutexLock lock(&mu_); - if (read_requested_.Set(payload_tag)) { - return ReadTicket(Failure{}, nullptr); + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::Schedule::CollectData2"); + for (size_t i = 0; i < scheduling_data.size(); ++i) { + SchedulingData& scheduling = scheduling_data[i]; + if (scheduling.reader == nullptr) continue; + scheduling.reader->mu_.Lock(); + auto delivery_data = scheduling.reader->send_rate_.GetDeliveryData(now); + bool reading = scheduling.reader->reading_; + if (reading) any_readers = true; + scheduling.reader->mu_.Unlock(); + scheduler_->AddChannel(i, reading, delivery_data.start_time, + delivery_data.bytes_per_second); + } + } + if (!any_readers) return; + { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::Schedule::MakePlan"); + scheduler_->MakePlan(*ztrace_collector_); + } + { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::Schedule::PlaceMessages"); + while (true) { + auto* message = frames_queue_.Peek(); + if (message == nullptr) break; + auto selected_reader = + scheduler_->AllocateMessage(message->frame.tokens()); + if (!selected_reader.has_value()) { + // No reader is ready to read this frame. + // We'll try again later. + break; + } + ztrace_collector_->Append([this, message, selected_reader]() { + return WriteLargeFrameHeaderTrace{message->payload_tag, + WriteSizeForFrame(*message), + *selected_reader}; + }); + SchedulingData& scheduling = scheduling_data[*selected_reader]; + scheduling.queued_bytes += WriteSizeForFrame(*message); + scheduling.frames.emplace_back(std::move(*message)); + frames_queue_.Pop(); + } + } + { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::Schedule::PublishSchedule"); + for (auto& scheduling : scheduling_data) { + if (scheduling.frames.empty()) continue; + auto& reader = scheduling.reader; + DCHECK_NE(reader.get(), nullptr); + reader->mu_.Lock(); + if (!reader->reading_) { + // Frames were assigned to this reader, but it's either not reading + // or not allocated anymore. + auto frames = std::move(scheduling.frames); + scheduling.frames.clear(); + reader->mu_.Unlock(); + for (auto& frame : frames) { + Write(frame.payload_tag, std::move(frame.frame)); + } + continue; + } + reader->send_rate_.StartSend(scheduling.queued_bytes); + reader->frames_ = std::move(scheduling.frames); + reader->reading_ = false; + auto waker = std::move(reader->waker_); + reader->mu_.Unlock(); + waker.WakeupAsync(); } } - return ReadTicket(payload_tag, Ref()); } -Poll> InputQueue::PollRead(uint64_t payload_tag) { +void OutputBuffers::Write(uint64_t payload_tag, + MpscQueued output_buffer) { + GRPC_LATENT_SEE_INNER_SCOPE("OutputBuffers::Write"); + GRPC_TRACE_LOG(chaotic_good, INFO) + << "CHAOTIC_GOOD: " << this + << " Queue data frame write, payload_tag=" << payload_tag; + mu_write_.Lock(); + frames_queue_.Push(QueuedFrame{payload_tag, std::move(output_buffer)}); + mu_write_.Unlock(); + WakeupScheduler(); +} + +/////////////////////////////////////////////////////////////////////////////// +// SecureFrameQueue + +void SecureFrameQueue::Write(SliceBuffer buffer) { + ReleasableMutexLock lock(&mu_); + uint32_t frame_length = buffer.Length(); + uint32_t frame_padding = + DataConnectionPadding(frame_length, encode_alignment_); + uint32_t header_padding = DataConnectionPadding( + TcpDataFrameHeader::kFrameHeaderSize, encode_alignment_); + auto slice = MutableSlice::CreateUninitialized( + TcpDataFrameHeader::kFrameHeaderSize + header_padding); + TcpDataFrameHeader{0, 0, frame_length}.Serialize(slice.data()); + if (header_padding != 0) { + memset(slice.data() + TcpDataFrameHeader::kFrameHeaderSize, 0, + frame_padding); + } + all_frames_.Append(Slice(std::move(slice))); + all_frames_.TakeAndAppend(buffer); + if (frame_padding != 0) { + auto padding = MutableSlice::CreateUninitialized(frame_padding); + memset(padding.data(), 0, frame_padding); + all_frames_.Append(Slice(std::move(padding))); + } + auto waker = std::move(read_waker_); + lock.Release(); + waker.Wakeup(); +} + +/////////////////////////////////////////////////////////////////////////////// +// InputQueues + +InputQueue::ReadTicket InputQueue::Read(uint64_t payload_tag) { MutexLock lock(&mu_); - if (!read_completed_.IsSet(payload_tag)) { - if (!closed_error_.ok()) return closed_error_; - read_wakers_.emplace(payload_tag, - GetContext()->MakeNonOwningWaker()); - return Pending{}; - } - auto it_buffer = read_buffers_.find(payload_tag); - // If a read is complete then it must either be in read_buffers_ or it - // was cancelled; if it was cancelled then we shouldn't be polling for - // it. - CHECK(it_buffer != read_buffers_.end()); - auto buffer = std::move(it_buffer->second); - read_buffers_.erase(it_buffer); - read_wakers_.erase(payload_tag); - return std::move(buffer); + if (read_requested_.Set(payload_tag)) { + return ReadTicket( + MakeRefCounted( + payload_tag, absl::UnavailableError("Duplicate read requested")), + nullptr); + } + auto it = completions_.find(payload_tag); + if (it != completions_.end()) { + return ReadTicket(it->second, nullptr); + } + auto completion = MakeRefCounted(payload_tag); + completions_.emplace(payload_tag, completion); + return ReadTicket(std::move(completion), Ref()); } void InputQueue::CompleteRead(uint64_t payload_tag, SliceBuffer buffer) { + GRPC_LATENT_SEE_INNER_SCOPE("InputQueue::CompleteRead"); if (payload_tag == 0) return; - Waker waker; - auto cleanup = absl::MakeCleanup([&waker]() { waker.Wakeup(); }); - MutexLock lock(&mu_); - GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: Complete payload_tag #" << payload_tag; - if (!closed_error_.ok()) return; - if (read_completed_.Set(payload_tag)) return; - read_buffers_.emplace(payload_tag, std::move(buffer)); - auto it = read_wakers_.find(payload_tag); - if (it != read_wakers_.end()) { - waker = std::move(it->second); - read_wakers_.erase(it); + mu_.Lock(); + if (!closed_error_.ok()) { + mu_.Unlock(); + return; + } + if (read_completed_.Set(payload_tag)) { + mu_.Unlock(); + return; } + auto c = completions_.extract(payload_tag); + if (!c.empty()) { + auto& completion = c.mapped(); + mu_.Unlock(); + completion->mu.Lock(); + completion->result.emplace(std::move(buffer)); + completion->ready = true; + auto waker = std::move(completion->waker); + completion->mu.Unlock(); + waker.Wakeup(); + return; + } + completions_.emplace( + payload_tag, MakeRefCounted(payload_tag, std::move(buffer))); + mu_.Unlock(); } -void InputQueue::Cancel(uint64_t payload_tag) { - Waker waker; - auto cleanup = absl::MakeCleanup([&waker]() { waker.Wakeup(); }); - MutexLock lock(&mu_); +void InputQueue::Cancel(Completion* completion) { + mu_.Lock(); GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: Cancel payload_tag #" << payload_tag; - auto it = read_wakers_.find(payload_tag); - if (it != read_wakers_.end()) { - waker = std::move(it->second); - read_wakers_.erase(it); + << "CHAOTIC_GOOD: Cancel payload_tag #" << completion->payload_tag; + read_completed_.Set(completion->payload_tag); + auto c = completions_.extract(completion->payload_tag); + if (!c.empty()) { + auto& completion = c.mapped(); + mu_.Unlock(); + completion->mu.Lock(); + auto waker = std::move(completion->waker); + completion->mu.Unlock(); + waker.Wakeup(); + } else { + mu_.Unlock(); } - read_buffers_.erase(payload_tag); - read_completed_.Set(payload_tag); } -void InputQueue::AddData(channelz::DataSink& sink) { - Json::Object data; +void InputQueue::AddData(channelz::DataSink sink) { MutexLock lock(&mu_); - data["read_requested"] = Json::FromString(absl::StrCat(read_requested_)); - data["read_completed"] = Json::FromString(absl::StrCat(read_completed_)); - if (!read_wakers_.empty()) { - Json::Array read_wakers; - for (const auto& [payload_tag, waker] : read_wakers_) { - read_wakers.emplace_back(Json::FromNumber(payload_tag)); - } - data["read_wakers"] = Json::FromArray(std::move(read_wakers)); - } - if (!read_buffers_.empty()) { - Json::Array read_buffers; - for (const auto& [payload_tag, buffer] : read_buffers_) { - Json::Object buffer_data; - buffer_data["payload_tag"] = Json::FromNumber(payload_tag); - buffer_data["bytes"] = Json::FromNumber(buffer.Length()); - read_buffers.emplace_back(Json::FromObject(std::move(buffer_data))); - } - data["read_buffers"] = Json::FromArray(std::move(read_buffers)); - } - if (!closed_error_.ok()) { - data["closed_error"] = Json::FromString(closed_error_.ToString()); - } - sink.AddAdditionalInfo("inputQueue", std::move(data)); + sink.AddData("input_queue", + channelz::PropertyList() + .Set("read_requested", absl::StrCat(read_requested_)) + .Set("read_completed", absl::StrCat(read_completed_)) + .Set("closed_error", closed_error_)); } void InputQueue::SetClosed(absl::Status status) { - absl::flat_hash_map read_wakers; - Waker closed_waker; - auto wake_up = absl::MakeCleanup([&]() { - for (auto& [_, waker] : read_wakers) waker.Wakeup(); - closed_waker.Wakeup(); - }); - MutexLock lock(&mu_); - if (!closed_error_.ok()) return; + mu_.Lock(); + if (!closed_error_.ok()) { + mu_.Unlock(); + return; + } if (status.ok()) status = absl::UnavailableError("transport closed"); closed_error_ = std::move(status); - read_wakers = std::move(read_wakers_); - read_wakers_.clear(); - closed_waker = std::move(await_closed_); + auto completions = std::move(completions_); + completions_.clear(); + Waker await_closed = std::move(await_closed_); + mu_.Unlock(); + await_closed.Wakeup(); + for (auto& [tag, completion] : completions) { + completion->mu.Lock(); + if (!completion->ready) { + auto waker = std::move(completion->waker); + completion->mu.Unlock(); + waker.Wakeup(); + } else { + completion->mu.Unlock(); + } + } } /////////////////////////////////////////////////////////////////////////////// @@ -472,119 +564,254 @@ TransportFramingEndpointExtension* GetTransportFramingEndpointExtension( TransportFramingEndpointExtension>( endpoint.GetEventEngineEndpoint().get()); } + +class MetricsCollector + : public RefCounted { + public: + explicit MetricsCollector( + Clock* clock, + grpc_event_engine::experimental::EventEngine::Endpoint& endpoint) + : clock_(clock), telemetry_info_(endpoint.GetTelemetryInfo()) { + if (telemetry_info_ == nullptr) return; + delivery_rate_ = telemetry_info_->GetMetricKey("delivery_rate"); + rtt_ = telemetry_info_->GetMetricKey("net_rtt_usec"); + if (!rtt_.has_value()) rtt_ = telemetry_info_->GetMetricKey("srtt"); + data_notsent_ = telemetry_info_->GetMetricKey("data_notsent"); + byte_offset_ = telemetry_info_->GetMetricKey("byte_offset"); + absl::InlinedVector keys; + if (delivery_rate_.has_value()) { + keys.push_back(*delivery_rate_); + } + if (byte_offset_.has_value()) keys.push_back(*byte_offset_); + if (rtt_.has_value()) keys.push_back(*rtt_); + if (data_notsent_.has_value()) keys.push_back(*data_notsent_); + requested_metrics_ = telemetry_info_->GetMetricsSet(keys); + } + + bool HasAnyMetrics() const { + return delivery_rate_.has_value() || rtt_.has_value() || + data_notsent_.has_value(); + } + + std::shared_ptr< + grpc_event_engine::experimental::EventEngine::Endpoint::MetricsSet> + requested_metrics() const { + return requested_metrics_; + } + + std::tuple> + GetNetworkMetrics( + grpc_event_engine::experimental::EventEngine::Endpoint::WriteEvent event, + absl::Span + metrics, + uint64_t message_size) const { + SendRate::NetworkMetrics net_metrics; + std::optional data_notsent; + std::optional byte_offset; + for (const auto& metric : metrics) { + if (metric.key == delivery_rate_) { + net_metrics.bytes_per_nanosecond = metric.value * 1e-9; + } + if (metric.key == rtt_ && metric.value > 0) { + net_metrics.rtt_usec = metric.value; + } + if (metric.key == data_notsent_) { + data_notsent = metric.value; + } + if (metric.key == byte_offset_) { + byte_offset = metric.value; + } + } + if (event != grpc_event_engine::experimental::EventEngine::Endpoint:: + WriteEvent::kSendMsg) { + byte_offset = std::nullopt; + data_notsent = std::nullopt; + } + std::optional bytes_outstanding; + if (byte_offset.has_value() && data_notsent.has_value()) { + bytes_outstanding = *data_notsent + message_size - *byte_offset; + } + return {net_metrics, bytes_outstanding}; + } + + grpc_event_engine::experimental::EventEngine::Endpoint::WriteEventSink + MakeWriteEventSink(size_t write_size, + RefCountedPtr reader, + std::shared_ptr ztrace_collector) { + using grpc_event_engine::experimental::EventEngine; + return EventEngine::Endpoint::WriteEventSink( + requested_metrics(), + {EventEngine::Endpoint::WriteEvent::kSendMsg, + EventEngine::Endpoint::WriteEvent::kSent, + EventEngine::Endpoint::WriteEvent::kAcked}, + [reader, ztrace_collector, write_size, self = Ref()]( + EventEngine::Endpoint::WriteEvent event, absl::Time timestamp, + std::vector metrics) { + GRPC_LATENT_SEE_PARENT_SCOPE("MetricsCollector::WriteEventSink"); + ztrace_collector->Append([event, timestamp, &metrics, + telemetry_info = self->telemetry_info_, + &reader]() { + EndpointWriteMetricsTrace trace{timestamp, event, {}, reader->id()}; + trace.metrics.reserve(metrics.size()); + for (const auto [id, value] : metrics) { + if (auto name = telemetry_info->GetMetricName(id); + name.has_value()) { + trace.metrics.push_back({*name, value}); + } + } + return trace; + }); + auto [net_metrics, data_notsent] = + self->GetNetworkMetrics(event, metrics, write_size); + std::optional network_send; + if (event == EventEngine::Endpoint::WriteEvent::kSent || + data_notsent.has_value()) { + network_send = SendRate::NetworkSend{ + self->clock_->Now() + + absl::ToInt64Nanoseconds(timestamp - absl::Now()), + static_cast(data_notsent.value_or(write_size))}; + } + reader->SetNetworkMetrics(network_send, net_metrics); + }); + } + + private: + Clock* const clock_; + std::optional delivery_rate_; + std::optional rtt_; + std::optional data_notsent_; + std::optional byte_offset_; + std::shared_ptr< + grpc_event_engine::experimental::EventEngine::Endpoint::MetricsSet> + requested_metrics_; + std::shared_ptr< + grpc_event_engine::experimental::EventEngine::Endpoint::TelemetryInfo> + telemetry_info_; +}; } // namespace -auto Endpoint::WriteLoop(uint32_t id, - RefCountedPtr output_buffers, - std::shared_ptr endpoint, - std::shared_ptr ztrace_collector) { - output_buffers->AddEndpoint(id); - std::vector requested_metrics; - std::optional data_rate_metric = - endpoint->GetEventEngineEndpoint()->GetMetricKey("delivery_rate"); - if (data_rate_metric.has_value()) { - requested_metrics.push_back(*data_rate_metric); - } - return Loop([id, endpoint = std::move(endpoint), - output_buffers = std::move(output_buffers), - requested_metrics = std::move(requested_metrics), - data_rate_metric, ztrace_collector]() { +auto Endpoint::PullDataPayload(RefCountedPtr ctx) { + return Map( + ctx->reader->Next(), + [ctx]( + ValueOrFailure> queued_frames) + -> ValueOrFailure { + if (!queued_frames.ok()) return Failure{}; + GRPC_TRACE_LOG(chaotic_good, INFO) + << "CHAOTIC_GOOD: " << ctx->reader.get() << " " + << ResolvedAddressToString(ctx->endpoint->GetPeerAddress()) + .value_or("peer-unknown") + << " Write " << queued_frames->size() + << " frames to data endpoint #" << ctx->id; + using grpc_event_engine::experimental::EventEngine; + + GRPC_LATENT_SEE_INNER_SCOPE("SerializePayload"); + // Frame everything into a slice buffer. + SliceBuffer buffer; + const size_t header_padding = DataConnectionPadding( + TcpDataFrameHeader::kFrameHeaderSize, ctx->encode_alignment); + const size_t header_size = + TcpDataFrameHeader::kFrameHeaderSize + header_padding; + auto header_frames = MutableSlice::CreateUninitialized( + header_size * queued_frames->size() + ctx->encode_alignment); + auto padding_mut = + header_frames.TakeFirstNoInline(ctx->encode_alignment); + memset(padding_mut.data(), 0, ctx->encode_alignment); + auto padding = Slice(std::move(padding_mut)); + for (size_t i = 0; i < queued_frames->size(); ++i) { + auto& queued_frame = (*queued_frames)[i]; + auto& frame = absl::ConvertVariantTo( + queued_frame.frame->payload); + auto hdr = header_frames.TakeFirstNoInline(header_size); + const uint32_t payload_length = frame.MakeHeader().payload_length; + TcpDataFrameHeader{queued_frame.payload_tag, ctx->clock->Now(), + payload_length} + .Serialize(hdr.data()); + memset(hdr.data() + TcpDataFrameHeader::kFrameHeaderSize, 0, + header_padding); + buffer.AppendIndexed(Slice(std::move(hdr))); + frame.SerializePayload(buffer); + const size_t frame_padding = + DataConnectionPadding(payload_length, ctx->encode_alignment); + if (frame_padding != 0) { + buffer.AppendIndexed(padding.RefSubSlice(0, frame_padding)); + } + } + return std::move(buffer); + }); +} + +auto Endpoint::WriteLoop(RefCountedPtr ctx) { + auto metrics_collector = MakeRefCounted( + ctx->clock, *ctx->endpoint->GetEventEngineEndpoint()); + if (!metrics_collector->HasAnyMetrics()) { + metrics_collector.reset(); + } + return Loop([ctx = std::move(ctx), + metrics_collector = std::move(metrics_collector)]() { return TrySeq( - output_buffers->Next(id), - [endpoint, id, - requested_metrics = absl::Span(requested_metrics), - data_rate_metric, output_buffers, - ztrace_collector](data_endpoints_detail::NextWrite next_write) { - GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: " << output_buffers.get() << " " - << ResolvedAddressToString(endpoint->GetPeerAddress()) - .value_or("peer-unknown") - << " Write " << next_write.bytes.Length() - << "b to data endpoint #" << id; - using grpc_event_engine::experimental::EventEngine; + GRPC_LATENT_SEE_PROMISE( + "DataEndpointPullPayload", + Race(PullDataPayload(ctx), + Map(ctx->secure_frame_queue->Next(), + [](auto x) -> ValueOrFailure { + return std::move(x); + }))), + [ctx, metrics_collector](SliceBuffer buffer) { + ctx->ztrace_collector->Append( + WriteBytesToEndpointTrace{buffer.Length(), ctx->id}); PromiseEndpoint::WriteArgs write_args; - if (next_write.trace && data_rate_metric.has_value()) { - write_args.set_metrics_sink(EventEngine::Endpoint::WriteEventSink( - requested_metrics, - {EventEngine::Endpoint::WriteEvent::kSendMsg, - EventEngine::Endpoint::WriteEvent::kScheduled, - EventEngine::Endpoint::WriteEvent::kAcked}, - [data_rate_metric, id, output_buffers, ztrace_collector, - endpoint = endpoint.get()]( - EventEngine::Endpoint::WriteEvent event, - absl::Time timestamp, - std::vector metrics) { - ztrace_collector->Append([event, timestamp, &metrics, - endpoint]() { - EndpointWriteMetricsTrace trace{timestamp, event, {}}; - trace.metrics.reserve(metrics.size()); - for (const auto [id, value] : metrics) { - if (auto name = - endpoint->GetEventEngineEndpoint()->GetMetricName( - id); - name.has_value()) { - trace.metrics.push_back({*name, value}); - } - } - return trace; - }); - for (const auto& metric : metrics) { - if (metric.key == *data_rate_metric) { - output_buffers->UpdateSendRate(id, metric.value * 1e-9); - } - } - })); + auto now = Timestamp::Now(); + if (metrics_collector != nullptr && + now - ctx->last_metrics_update > Duration::Milliseconds(100)) { + ctx->last_metrics_update = now; + write_args.set_metrics_sink(metrics_collector->MakeWriteEventSink( + buffer.Length(), ctx->reader, ctx->ztrace_collector)); } - ztrace_collector->Append(WriteBytesToEndpointTrace{ - next_write.bytes.Length(), id, next_write.trace}); return Map( AddGeneratedErrorPrefix( - [id, endpoint]() { + [ctx]() { return absl::StrCat( "DATA_CHANNEL: ", - ResolvedAddressToString(endpoint->GetPeerAddress()) + ResolvedAddressToString(ctx->endpoint->GetPeerAddress()) .value_or("peer-unknown"), - "#", id); + "#", ctx->id); }, GRPC_LATENT_SEE_PROMISE( "DataEndpointWrite", - endpoint->Write(std::move(next_write.bytes), - std::move(write_args)))), - [id, output_buffers, ztrace_collector](absl::Status status) { - ztrace_collector->Append([id, &status]() { + ctx->endpoint->Write(std::move(buffer), + std::move(write_args)))), + [ctx](absl::Status status) { + ctx->ztrace_collector->Append([id = ctx->id, &status]() { return FinishWriteBytesToEndpointTrace{id, status}; }); GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: " << output_buffers.get() << " " - << "Write done to data endpoint #" << id + << "CHAOTIC_GOOD: " << ctx->reader.get() << " " + << "Write done to data endpoint #" << ctx->id << " status: " << status; return status; }); }, - [id, output_buffers]() -> LoopCtl { + [id = ctx->id, reader = ctx->reader]() -> LoopCtl { GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: " << output_buffers.get() << " " + << "CHAOTIC_GOOD: " << reader.get() << " " << "Write done to data endpoint #" << id; return Continue{}; }); }); } -auto Endpoint::ReadLoop(uint32_t id, uint32_t decode_alignment, - RefCountedPtr input_queues, - std::shared_ptr endpoint, - std::shared_ptr ztrace_collector) { - return Loop([id, decode_alignment, endpoint = std::move(endpoint), - input_queues = std::move(input_queues), - ztrace_collector = std::move(ztrace_collector)]() { +auto Endpoint::ReadLoop(RefCountedPtr ctx) { + return Loop([ctx = std::move(ctx)]() { return TrySeq( GRPC_LATENT_SEE_PROMISE( "DataEndpointReadHdr", - endpoint->ReadSlice( + ctx->endpoint->ReadSlice( TcpDataFrameHeader::kFrameHeaderSize + DataConnectionPadding(TcpDataFrameHeader::kFrameHeaderSize, - decode_alignment))), - [id](Slice frame_header) { + ctx->decode_alignment))), + [id = ctx->id](Slice frame_header) { auto hdr = TcpDataFrameHeader::Parse(frame_header.data()); GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: Read " @@ -592,18 +819,17 @@ auto Endpoint::ReadLoop(uint32_t id, uint32_t decode_alignment, << " on data connection #" << id; return hdr; }, - [endpoint, ztrace_collector, id, - decode_alignment](TcpDataFrameHeader frame_header) { - ztrace_collector->Append(ReadDataHeaderTrace{frame_header}); + [ctx](TcpDataFrameHeader frame_header) { + ctx->ztrace_collector->Append(ReadDataHeaderTrace{frame_header}); return Map( TryStaple(GRPC_LATENT_SEE_PROMISE( "DataEndpointRead", - endpoint->Read(frame_header.payload_length + - DataConnectionPadding( - frame_header.payload_length, - decode_alignment))), + ctx->endpoint->Read(frame_header.payload_length + + DataConnectionPadding( + frame_header.payload_length, + ctx->decode_alignment))), frame_header), - [id, frame_header](auto x) { + [id = ctx->id, frame_header](auto x) { GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: Complete read " << frame_header << " on data connection #" << id @@ -611,21 +837,20 @@ auto Endpoint::ReadLoop(uint32_t id, uint32_t decode_alignment, return x; }); }, - [endpoint, input_queues, id, decode_alignment]( - std::tuple buffer_frame) + [ctx](std::tuple buffer_frame) -> LoopCtl { auto& [buffer, frame_header] = buffer_frame; GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: Complete read " << frame_header - << " on data connection #" << id; + << " on data connection #" << ctx->id; buffer.RemoveLastNBytesNoInline(DataConnectionPadding( - frame_header.payload_length, decode_alignment)); + frame_header.payload_length, ctx->decode_alignment)); if (GPR_UNLIKELY(frame_header.payload_tag == kSecurityFramePayloadTag)) { - ReceiveSecurityFrame(*endpoint, std::move(buffer)); + ReceiveSecurityFrame(*ctx->endpoint, std::move(buffer)); } else { - input_queues->CompleteRead(frame_header.payload_tag, - std::move(buffer)); + ctx->input_queues->CompleteRead(frame_header.payload_tag, + std::move(buffer)); } return Continue{}; }); @@ -640,98 +865,118 @@ void Endpoint::ReceiveSecurityFrame(PromiseEndpoint& endpoint, transport_framing_endpoint_extension->ReceiveFrame(std::move(buffer)); } -Endpoint::Endpoint(uint32_t id, uint32_t decode_alignment, +void Endpoint::AddData(channelz::DataSink sink) { + sink.AddData( + absl::StrCat("endpoint", ctx_->id), + channelz::PropertyList() + .Set("now", ctx_->clock->Now()) + .Set("encode_alignment", ctx_->encode_alignment) + .Set("decode_alignment", ctx_->decode_alignment) + .Set("secure_frame_bytes_queued", + [this]() -> std::optional { + if (ctx_->secure_frame_queue.Get() == nullptr) { + return std::nullopt; + } + return ctx_->secure_frame_queue->InstantaneousQueuedBytes(); + }()) + .Set("enable_tracing", ctx_->enable_tracing) + .Merge(ctx_->reader->ChannelzProperties())); + party_->ExportToChannelz(absl::StrCat("endpoint_party", ctx_->id), sink); +} + +Endpoint::Endpoint(uint32_t id, uint32_t encode_alignment, + uint32_t decode_alignment, Clock* clock, RefCountedPtr output_buffers, RefCountedPtr input_queues, PendingConnection pending_connection, bool enable_tracing, TransportContextPtr ctx, - std::shared_ptr ztrace_collector) - : ztrace_collector_(ztrace_collector), id_(id) { - auto arena = SimpleArenaAllocator(0)->MakeArena(); - arena->SetContext(ctx->event_engine.get()); - party_ = Party::Make(arena); + std::shared_ptr ztrace_collector) { + auto ep_ctx = MakeRefCounted(); + ctx_ = ep_ctx; + ep_ctx->id = id; + ep_ctx->encode_alignment = encode_alignment; + ep_ctx->decode_alignment = decode_alignment; + ep_ctx->enable_tracing = enable_tracing; + ep_ctx->output_buffers = std::move(output_buffers); + ep_ctx->input_queues = std::move(input_queues); + ep_ctx->ztrace_collector = std::move(ztrace_collector); + ep_ctx->arena = SimpleArenaAllocator(0)->MakeArena(); + ep_ctx->arena->SetContext(ctx->event_engine.get()); + ep_ctx->clock = clock; + ep_ctx->transport_ctx = std::move(ctx); + ep_ctx->reader = ep_ctx->output_buffers->MakeReader(ep_ctx->id); + party_ = Party::Make(ep_ctx->arena); party_->Spawn( "write", - [id, decode_alignment, enable_tracing, - output_buffers = std::move(output_buffers), input_queues, - pending_connection = std::move(pending_connection), - arena = std::move(arena), ctx = std::move(ctx), - ztrace_collector = std::move(ztrace_collector)]() mutable { + [ep_ctx, pending_connection = std::move(pending_connection)]() mutable { return TrySeq( pending_connection.Await(), - [id, decode_alignment, enable_tracing, - output_buffers = std::move(output_buffers), - input_queues = std::move(input_queues), arena = std::move(arena), - ctx = std::move(ctx), - ztrace_collector = - std::move(ztrace_collector)](PromiseEndpoint ep) mutable { + [ep_ctx = std::move(ep_ctx)](PromiseEndpoint ep) mutable { GRPC_TRACE_LOG(chaotic_good, INFO) - << "CHAOTIC_GOOD: data endpoint " << id << " to " + << "CHAOTIC_GOOD: data endpoint " << ep_ctx->id << " to " << grpc_event_engine::experimental::ResolvedAddressToString( ep.GetPeerAddress()) .value_or("<>") << " ready"; RefCountedPtr socket_node; - if (ctx->socket_node != nullptr) { + if (ep_ctx->transport_ctx->socket_node != nullptr) { auto* channelz_endpoint = grpc_event_engine::experimental::QueryExtension< grpc_event_engine::experimental::ChannelzExtension>( ep.GetEventEngineEndpoint().get()); - socket_node = MakeSocketNode(ctx, ep); - socket_node->AddParent(ctx->socket_node.get()); + socket_node = MakeSocketNode(ep_ctx->transport_ctx, ep); + socket_node->AddParent( + ep_ctx->transport_ctx->socket_node.get()); if (channelz_endpoint != nullptr) { channelz_endpoint->SetSocketNode(socket_node); } } auto endpoint = std::make_shared(std::move(ep)); + ep_ctx->endpoint = endpoint; // Enable RxMemoryAlignment and RPC receive coalescing after the // transport setup is complete. At this point all the settings // frames should have been read. - if (decode_alignment != 1) { + if (ep_ctx->decode_alignment != 1) { endpoint->EnforceRxMemoryAlignmentAndCoalescing(); } - if (enable_tracing) { + if (ep_ctx->enable_tracing) { auto* epte = grpc_event_engine::experimental::QueryExtension< grpc_event_engine::experimental::TcpTraceExtension>( endpoint->GetEventEngineEndpoint().get()); if (epte != nullptr) { epte->SetTcpTracer(std::make_shared( - ctx->stats_plugin_group)); + ep_ctx->transport_ctx->stats_plugin_group)); } } + ep_ctx->secure_frame_queue.Set( + MakeRefCounted(ep_ctx->encode_alignment)); auto* transport_framing_endpoint_extension = GetTransportFramingEndpointExtension(*endpoint); if (transport_framing_endpoint_extension != nullptr) { transport_framing_endpoint_extension->SetSendFrameCallback( - [id, output_buffers](SliceBuffer* data) { - output_buffers->WriteSecurityFrame(id, std::move(*data)); + [ep_ctx](SliceBuffer* data) { + ep_ctx->secure_frame_queue->Write(std::move(*data)); }); } - auto read_party = Party::Make(std::move(arena)); + auto read_party = Party::Make(ep_ctx->arena); read_party->Spawn( "read", - [id, decode_alignment, input_queues, endpoint, - ztrace_collector]() { - return ReadLoop(id, decode_alignment, input_queues, - endpoint, ztrace_collector); - }, - [input_queues](absl::Status status) { + [ep_ctx]() mutable { return ReadLoop(std::move(ep_ctx)); }, + [ep_ctx](absl::Status status) { GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: read party done: " << status; - input_queues->SetClosed(std::move(status)); - }); - return Map( - WriteLoop(id, std::move(output_buffers), std::move(endpoint), - std::move(ztrace_collector)), - [read_party, socket_node = std::move(socket_node)](auto x) { - return x; + ep_ctx->input_queues->SetClosed(std::move(status)); }); + return Map(GRPC_LATENT_SEE_PROMISE("DataEndpointWrite", + WriteLoop(std::move(ep_ctx))), + [read_party, socket_node = std::move(socket_node)]( + auto x) { return x; }); }); }, - [input_queues](absl::Status status) { + [ep_ctx](absl::Status status) { GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: write party done: " << status; - input_queues->SetClosed(std::move(status)); + ep_ctx->input_queues->SetClosed(std::move(status)); }); } @@ -744,14 +989,34 @@ DataEndpoints::DataEndpoints( std::vector endpoints_vec, TransportContextPtr ctx, uint32_t encode_alignment, uint32_t decode_alignment, std::shared_ptr ztrace_collector, bool enable_tracing, - data_endpoints_detail::Clock* clock) - : output_buffers_(MakeRefCounted( - clock, encode_alignment, ztrace_collector, ctx)), - input_queues_(MakeRefCounted(ctx)) { + std::string scheduler_config, data_endpoints_detail::Clock* clock) + : channelz::DataSource(ctx->socket_node), + output_buffers_(MakeRefCounted( + clock, encode_alignment, ztrace_collector, + std::move(scheduler_config), ctx)), + input_queues_(MakeRefCounted()) { for (size_t i = 0; i < endpoints_vec.size(); ++i) { endpoints_.emplace_back(std::make_unique( - i, decode_alignment, output_buffers_, input_queues_, - std::move(endpoints_vec[i]), enable_tracing, ctx, ztrace_collector)); + i, encode_alignment, decode_alignment, clock, output_buffers_, + input_queues_, std::move(endpoints_vec[i]), enable_tracing, ctx, + ztrace_collector)); + } + SourceConstructed(); +} + +void DataEndpoints::AddData(channelz::DataSink sink) { + output_buffers_->AddData(sink); + input_queues_->AddData(sink); + struct EndpointInfoCollector { + explicit EndpointInfoCollector(int remaining) + : remaining(remaining), endpoints(remaining) {} + Mutex mu; + int remaining ABSL_GUARDED_BY(mu) = 0; + Json::Array endpoints ABSL_GUARDED_BY(mu); + }; + MutexLock lock(&mu_); + for (size_t i = 0; i < endpoints_.size(); ++i) { + endpoints_[i]->AddData(sink); } } diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.h b/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.h index 789c5ed8995..16dbba575d5 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/data_endpoints.h @@ -20,13 +20,18 @@ #include #include #include +#include #include "src/core/channelz/channelz.h" +#include "src/core/channelz/property_list.h" +#include "src/core/ext/transport/chaotic_good/frame_transport.h" #include "src/core/ext/transport/chaotic_good/pending_connection.h" +#include "src/core/ext/transport/chaotic_good/scheduler.h" #include "src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h" #include "src/core/ext/transport/chaotic_good/transport_context.h" +#include "src/core/lib/promise/loop.h" +#include "src/core/lib/promise/mpsc.h" #include "src/core/lib/promise/party.h" -#include "src/core/lib/promise/status_flag.h" #include "src/core/lib/slice/slice_buffer.h" #include "src/core/lib/transport/promise_endpoint.h" #include "src/core/util/seq_bit_set.h" @@ -49,109 +54,236 @@ class SendRate { explicit SendRate( double initial_rate = 0 /* <=0 ==> not set, bytes per nanosecond */) : current_rate_(initial_rate) {} - void StartSend(uint64_t current_time, uint64_t send_size); - void MaybeCompleteSend(uint64_t current_time); - void SetCurrentRate(double bytes_per_nanosecond); + + struct NetworkSend { + uint64_t start_time; + uint64_t bytes; + }; + struct NetworkMetrics { + std::optional rtt_usec; + std::optional bytes_per_nanosecond; + }; + void StartSend(uint64_t bytes) { last_send_bytes_outstanding_ += bytes; } + void SetNetworkMetrics(const std::optional& network_send, + const NetworkMetrics& metrics); bool IsRateMeasurementStale() const; - // Returns double nanoseconds from now. - LbDecision GetLbDecision(uint64_t current_time, size_t bytes); - void AddData(Json::Object& obj) const; + channelz::PropertyList ChannelzProperties() const; void PerformRateProbe() { last_rate_measurement_ = Timestamp::Now(); } + struct DeliveryData { + // Time in seconds of the time that a byte sent now would be received at the + // peer. + double start_time; + // The rate of bytes per second that a channel is expected to send. + double bytes_per_second; + }; + DeliveryData GetDeliveryData(uint64_t current_time) const; + private: - uint64_t send_start_time_ = 0; - uint64_t send_size_ = 0; - double current_rate_; // bytes per nanosecond + uint64_t last_send_started_time_ = 0; + uint64_t last_send_bytes_outstanding_ = 0; + double current_rate_; // bytes per nanosecond + uint64_t rtt_usec_ = 0.0; // nanoseconds Timestamp last_rate_measurement_ = Timestamp::ProcessEpoch(); }; -struct NextWrite { - SliceBuffer bytes; - bool trace; -}; - -// Buffered writes for one data endpoint -class OutputBuffer { +// The set of output buffers for all connected data endpoints +class OutputBuffers final + : public DualRefCounted { public: - LbDecision GetLbDecision(uint64_t current_time, size_t bytes); - SliceBuffer& pending() { return pending_; } - Waker TakeWaker() { return std::move(flush_waker_); } - void SetWaker() { - flush_waker_ = GetContext()->MakeNonOwningWaker(); + OutputBuffers(Clock* clock, uint32_t encode_alignment, + std::shared_ptr ztrace_collector, + std::string scheduler_config, TransportContextPtr ctx) + : encode_alignment_(encode_alignment), + clock_(clock), + ztrace_collector_(std::move(ztrace_collector)), + ctx_(std::move(ctx)), + scheduling_party_(Party::Make(arena_)), + scheduler_(MakeScheduler(std::move(scheduler_config))) { + scheduling_party_->Spawn( + "output-buffers-scheduler", + [self = WeakRef()]() mutable { + return Loop([self]() { + return Seq([self]() { return self->SchedulerPollForWork(); }, + [self]() -> LoopCtl { + self->Schedule(); + return Continue{}; + }); + }); + }, + [](absl::Status) {}); } - bool HavePending() const { return pending_.Length() > 0; } - NextWrite TakePendingAndStartWrite(uint64_t current_time); - void MaybeCompleteSend(uint64_t current_time); - void UpdateSendRate(double bytes_per_nanosecond) { - send_rate_.SetCurrentRate(bytes_per_nanosecond); + + ~OutputBuffers() { + auto scheduling_state = scheduling_state_.load(std::memory_order_acquire); + switch (scheduling_state) { + case kSchedulingProcessing: + case kSchedulingWorkAvailable: + break; + default: + delete reinterpret_cast(scheduling_state); + break; + } } - void AddData(Json::Object& obj) const; + void Orphaned() override { scheduling_party_.reset(); } - private: - Waker flush_waker_; - SliceBuffer pending_; - SendRate send_rate_; -}; + struct QueuedFrame final { + uint64_t payload_tag; + MpscQueued frame; + }; -// The set of output buffers for all connected data endpoints -class OutputBuffers final : public RefCounted, - public channelz::DataSource { - public: - OutputBuffers(Clock* clock, uint32_t encode_alignment, - std::shared_ptr ztrace_collector, - TransportContextPtr ctx) - : channelz::DataSource(ctx->socket_node), - ztrace_collector_(std::move(ztrace_collector)), - encode_alignment_(encode_alignment), - clock_(clock) {} - ~OutputBuffers() override { ResetDataSource(); } - - void AddData(channelz::DataSink& sink) override; - - auto Write(uint64_t payload_tag, SliceBuffer output_buffer, - std::shared_ptr call_tracer) { - return [payload_tag, send_time = clock_->Now(), - output_buffer = std::move(output_buffer), - call_tracer = std::move(call_tracer), this]() mutable { - return PollWrite(payload_tag, send_time, output_buffer, call_tracer); + class Reader final : public RefCounted { + public: + // Don't call directly: use MakeReader instead. + explicit Reader(RefCountedPtr output_buffers, uint32_t id) + : output_buffers_(std::move(output_buffers)), id_(id) {} + ~Reader() { CHECK(dropped_); } + Reader(const Reader&) = delete; + Reader& operator=(const Reader&) = delete; + + auto Next() { return NextPromise(this); } + uint32_t id() const { return id_; } + void SetNetworkMetrics( + const std::optional& network_send, + const SendRate::NetworkMetrics& metrics); + channelz::PropertyList ChannelzProperties(); + void Drop() { + CHECK(!dropped_); + dropped_ = true; + output_buffers_->DestroyReader(id_); + } + + private: + friend class OutputBuffers; + + class NextPromise { + public: + explicit NextPromise(Reader* reader) : reader_(reader) {} + + ~NextPromise() { + if (reader_ != nullptr) { + reader_->EndReadNext(); + } + } + + NextPromise(const NextPromise&) = delete; + NextPromise& operator=(const NextPromise&) = delete; + NextPromise(NextPromise&& other) noexcept + : reader_(std::exchange(other.reader_, nullptr)) {} + NextPromise& operator=(NextPromise&& other) noexcept { + std::swap(reader_, other.reader_); + return *this; + } + + Poll> operator()() { + auto r = reader_->PollReadNext(); + if (r.ready()) reader_ = nullptr; + return r; + } + + private: + Reader* reader_; }; - } - void WriteSecurityFrame(uint32_t connection_id, SliceBuffer output_buffer); + void EndReadNext(); + Poll> PollReadNext(); - auto Next(uint32_t connection_id) { - return [this, connection_id]() { return PollNext(connection_id); }; - } + const RefCountedPtr output_buffers_; + const uint32_t id_; + + Mutex mu_; + bool reading_ ABSL_GUARDED_BY(mu_) = false; + bool dropped_{false}; + SendRate send_rate_ ABSL_GUARDED_BY(mu_); + Waker waker_ ABSL_GUARDED_BY(mu_); + std::vector frames_ ABSL_GUARDED_BY(mu_); + }; - void AddEndpoint(uint32_t connection_id); + void AddData(channelz::DataSink sink); - uint32_t ReadyEndpoints() const { - return ready_endpoints_.load(std::memory_order_relaxed); + void Write(uint64_t payload_tag, MpscQueued output_buffer); + + size_t ReadyEndpoints() const { + return num_readers_.load(std::memory_order_relaxed); } - void UpdateSendRate(uint32_t connection_id, double bytes_per_nanosecond); + [[nodiscard]] RefCountedPtr MakeReader(uint32_t id) + ABSL_LOCKS_EXCLUDED(mu_reader_data_); + + void SetMpscProbe(MpscProbe probe) { + MutexLock lock(&mu_reader_data_); + mpsc_probe_ = std::move(probe); + } private: - Poll PollWrite(uint64_t payload_tag, uint64_t send_time, - SliceBuffer& output_buffer, - std::shared_ptr& call_tracer); - Poll PollNext(uint32_t connection_id); - void UpdateMetrics(size_t output_buffer, const TcpConnectionMetrics& metrics); + struct SchedulingData { + explicit SchedulingData(RefCountedPtr reader) + : reader(std::move(reader)) {} + RefCountedPtr reader; + std::vector frames; + uint64_t queued_bytes = 0; + }; - const std::shared_ptr ztrace_collector_; - Mutex mu_; - std::vector> buffers_ ABSL_GUARDED_BY(mu_); - Waker write_waker_ ABSL_GUARDED_BY(mu_); - std::atomic ready_endpoints_{0}; + static constexpr uintptr_t kSchedulingWorkAvailable = 1; + static constexpr uintptr_t kSchedulingProcessing = 2; + + void DestroyReader(uint32_t id) ABSL_LOCKS_EXCLUDED(mu_reader_data_); + + void WakeupScheduler(); + Poll SchedulerPollForWork(); + void Schedule() ABSL_LOCKS_EXCLUDED(mu_reader_data_); + + uint64_t WriteSizeForFrame(const QueuedFrame& queued_frame) { + auto& frame = + absl::ConvertVariantTo(queued_frame.frame->payload); + const auto hdr = frame.MakeHeader(); + const size_t length = hdr.payload_length; + return TcpDataFrameHeader::kFrameHeaderSize + + DataConnectionPadding(TcpDataFrameHeader::kFrameHeaderSize, + encode_alignment_) + + length + DataConnectionPadding(length, encode_alignment_); + } + + std::atomic num_readers_ = 0; + Mutex mu_reader_data_; + MpscProbe mpsc_probe_ ABSL_GUARDED_BY(mu_reader_data_); + std::vector> readers_ ABSL_GUARDED_BY(mu_reader_data_); const uint32_t encode_alignment_; Clock* const clock_; + const std::shared_ptr ztrace_collector_; + TransportContextPtr ctx_; + RefCountedPtr arena_ = [ctx = ctx_]() { + auto arena = SimpleArenaAllocator()->MakeArena(); + arena->SetContext( + ctx->event_engine.get()); + return arena; + }(); + // Must be held to push into big_frames_queue_ or small_frames_queue_. + Mutex mu_write_; + ArenaSpsc frames_queue_{arena_.get()}; + std::atomic scheduling_state_{kSchedulingProcessing}; + RefCountedPtr scheduling_party_; + const std::unique_ptr scheduler_; }; -class InputQueue final : public RefCounted, channelz::DataSource { +class InputQueue final : public RefCounted { + private: + struct Completion : public RefCounted { + Completion(uint64_t payload_tag, absl::StatusOr result) + : payload_tag(payload_tag), result(std::move(result)), ready(true) {} + explicit Completion(uint64_t payload_tag) + : payload_tag(payload_tag), ready(false) {} + Mutex mu; + const uint64_t payload_tag; + absl::StatusOr result ABSL_GUARDED_BY(mu); + bool ready ABSL_GUARDED_BY(mu); + Waker waker ABSL_GUARDED_BY(mu); + }; + public: // One outstanding read. - // ReadTickets get filed by read requests, and all tickets are fullfilled + // ReadTickets get filed by read requests, and all tickets are fulfilled // by an endpoint. // A call may Await a ticket to get the bytes back later (or it may skip that // step - in which case the bytes are thrown away after reading). @@ -159,60 +291,101 @@ class InputQueue final : public RefCounted, channelz::DataSource { // cause data corruption for other calls. class ReadTicket { public: - ReadTicket(ValueOrFailure payload_tag, + ReadTicket(RefCountedPtr completion, RefCountedPtr input_queues) - : payload_tag_(payload_tag), input_queues_(std::move(input_queues)) {} + : completion_(std::move(completion)), + input_queues_(std::move(input_queues)) {} ReadTicket(const ReadTicket&) = delete; ReadTicket& operator=(const ReadTicket&) = delete; ReadTicket(ReadTicket&& other) noexcept - : payload_tag_(std::exchange(other.payload_tag_, 0)), + : completion_(std::move(other.completion_)), input_queues_(std::move(other.input_queues_)) {} ReadTicket& operator=(ReadTicket&& other) noexcept { - payload_tag_ = std::exchange(other.payload_tag_, 0); + completion_ = std::move(other.completion_); input_queues_ = std::move(other.input_queues_); return *this; } ~ReadTicket() { - if (input_queues_ != nullptr && payload_tag_.ok() && *payload_tag_ != 0) { - input_queues_->Cancel(*payload_tag_); + if (input_queues_ != nullptr) { + completion_->mu.Lock(); + if (!completion_->ready) { + completion_->mu.Unlock(); + input_queues_->Cancel(completion_.get()); + } else { + completion_->mu.Unlock(); + } } } auto Await() { - return If( - payload_tag_.ok(), - [this]() { - return [input_queues = input_queues_, - payload_tag = std::exchange(*payload_tag_, 0)]() { - return input_queues->PollRead(payload_tag); - }; - }, - []() { - return []() -> absl::StatusOr { - return absl::InternalError("Duplicate read of tagged payload"); - }; - }); + class AwaitPromise { + public: + AwaitPromise(RefCountedPtr completion, + RefCountedPtr input_queues) + : completion_(std::move(completion)), + input_queues_(std::move(input_queues)) {} + + ~AwaitPromise() { + if (input_queues_ != nullptr) { + completion_->mu.Lock(); + if (!completion_->ready) { + completion_->mu.Unlock(); + input_queues_->Cancel(completion_.get()); + } else { + completion_->mu.Unlock(); + } + } + } + + AwaitPromise(const AwaitPromise&) = delete; + AwaitPromise& operator=(const AwaitPromise&) = delete; + AwaitPromise(AwaitPromise&& other) noexcept + : completion_(std::move(other.completion_)), + input_queues_(std::move(other.input_queues_)) {} + AwaitPromise& operator=(AwaitPromise&& other) noexcept { + completion_ = std::move(other.completion_); + input_queues_ = std::move(other.input_queues_); + return *this; + } + + Poll> operator()() { + DCHECK(completion_ != nullptr); + completion_->mu.Lock(); + if (completion_->ready) { + auto result = std::move(completion_->result); + completion_->mu.Unlock(); + input_queues_.reset(); + return std::move(result); + } + completion_->waker = GetContext()->MakeNonOwningWaker(); + completion_->mu.Unlock(); + return Pending{}; + } + + private: + RefCountedPtr completion_; + RefCountedPtr input_queues_; + }; + return AwaitPromise(std::move(completion_), std::move(input_queues_)); } private: - ValueOrFailure payload_tag_; + RefCountedPtr completion_; RefCountedPtr input_queues_; }; - explicit InputQueue(TransportContextPtr ctx) - : channelz::DataSource(ctx->socket_node) { + InputQueue() { read_requested_.Set(0); read_completed_.Set(0); } - ~InputQueue() override { ResetDataSource(); } ReadTicket Read(uint64_t payload_tag); void CompleteRead(uint64_t payload_tag, SliceBuffer buffer); - void Cancel(uint64_t payload_tag); + void Cancel(Completion* completion); - void AddData(channelz::DataSink& sink) override; + void AddData(channelz::DataSink sink); void SetClosed(absl::Status status); auto AwaitClosed() { @@ -229,21 +402,52 @@ class InputQueue final : public RefCounted, channelz::DataSource { private: struct Cancelled {}; - Poll> PollRead(uint64_t payload_tag); - Mutex mu_; SeqBitSet read_requested_ ABSL_GUARDED_BY(mu_); SeqBitSet read_completed_ ABSL_GUARDED_BY(mu_); - absl::flat_hash_map read_wakers_ ABSL_GUARDED_BY(mu_); - absl::flat_hash_map read_buffers_ ABSL_GUARDED_BY(mu_); + absl::flat_hash_map> completions_ + ABSL_GUARDED_BY(mu_); absl::Status closed_error_ ABSL_GUARDED_BY(mu_); Waker await_closed_ ABSL_GUARDED_BY(mu_); }; +class SecureFrameQueue + : public RefCounted { + public: + explicit SecureFrameQueue(uint32_t encode_alignment) + : encode_alignment_(encode_alignment) {} + + void Write(SliceBuffer buffer); + + auto Next() { + return [this]() -> Poll { + MutexLock lock(&mu_); + if (all_frames_.Length() == 0) { + read_waker_ = GetContext()->MakeNonOwningWaker(); + return Pending{}; + } + SliceBuffer buffer = std::move(all_frames_); + all_frames_.Clear(); + return buffer; + }; + } + + size_t InstantaneousQueuedBytes() { + MutexLock lock(&mu_); + return all_frames_.Length(); + } + + private: + Mutex mu_; + const uint32_t encode_alignment_; + SliceBuffer all_frames_ ABSL_GUARDED_BY(mu_); + Waker read_waker_ ABSL_GUARDED_BY(mu_); +}; + class Endpoint final { public: - Endpoint(uint32_t id, uint32_t decode_alignment, - RefCountedPtr output_buffers, + Endpoint(uint32_t id, uint32_t encode_alignment, uint32_t decode_alignment, + Clock* clock, RefCountedPtr output_buffers, RefCountedPtr input_queues, PendingConnection pending_connection, bool enable_tracing, TransportContextPtr ctx, @@ -252,29 +456,45 @@ class Endpoint final { Endpoint& operator=(const Endpoint&) = delete; Endpoint(Endpoint&&) = delete; Endpoint& operator=(Endpoint&&) = delete; - ~Endpoint() { ztrace_collector_->Append(EndpointCloseTrace{id_}); } + ~Endpoint() { + ctx_->ztrace_collector->Append(EndpointCloseTrace{ctx_->id}); + ctx_->reader->Drop(); + } + + void AddData(channelz::DataSink sink); private: - static auto WriteLoop(uint32_t id, - RefCountedPtr output_buffers, - std::shared_ptr endpoint, - std::shared_ptr ztrace_collector); - static auto ReadLoop(uint32_t id, uint32_t decode_alignment, - RefCountedPtr input_queues, - std::shared_ptr endpoint, - std::shared_ptr ztrace_collector); + struct EndpointContext : public RefCounted { + uint32_t id; + uint32_t encode_alignment; + uint32_t decode_alignment; + bool enable_tracing; + // TODO(ctiller): Inline members into EndpointContext. + RefCountedPtr output_buffers; + RefCountedPtr input_queues; + SingleSetRefCountedPtr secure_frame_queue; + std::shared_ptr endpoint; + std::shared_ptr ztrace_collector; + TransportContextPtr transport_ctx; + RefCountedPtr arena; + Clock* clock; + RefCountedPtr reader; + Timestamp last_metrics_update = Timestamp::ProcessEpoch(); + }; + + static auto PullDataPayload(RefCountedPtr ctx); + static auto WriteLoop(RefCountedPtr ctx); + static auto ReadLoop(RefCountedPtr ctx); static void ReceiveSecurityFrame(PromiseEndpoint& endpoint, SliceBuffer buffer); - - const std::shared_ptr ztrace_collector_; - const uint32_t id_; + RefCountedPtr ctx_; RefCountedPtr party_; }; } // namespace data_endpoints_detail // Collection of data connections. -class DataEndpoints { +class DataEndpoints final : public channelz::DataSource { public: using ReadTicket = data_endpoints_detail::InputQueue::ReadTicket; @@ -282,8 +502,11 @@ class DataEndpoints { TransportContextPtr ctx, uint32_t encode_alignment, uint32_t decode_alignment, std::shared_ptr ztrace_collector, - bool enable_tracing, + bool enable_tracing, std::string scheduler_config, data_endpoints_detail::Clock* clock = DefaultClock()); + ~DataEndpoints() { SourceDestructing(); } + + void AddData(channelz::DataSink sink) override; // Try to queue output_buffer against a data endpoint. // Returns a promise that resolves to the data endpoint connection id @@ -291,10 +514,8 @@ class DataEndpoints { // Connection ids returned by this class are 0 based (which is different // to how chaotic good communicates them on the wire - those are 1 based // to allow for the control channel identification) - auto Write(uint64_t tag, SliceBuffer output_buffer, - std::shared_ptr call_tracer) { - return output_buffers_->Write(tag, std::move(output_buffer), - std::move(call_tracer)); + void Write(uint64_t tag, MpscQueued output_buffer) { + output_buffers_->Write(tag, std::move(output_buffer)); } ReadTicket Read(uint64_t tag) { return input_queues_->Read(tag); } @@ -303,6 +524,10 @@ class DataEndpoints { bool empty() const { return output_buffers_->ReadyEndpoints() == 0; } + void SetMpscProbe(MpscProbe probe) { + output_buffers_->SetMpscProbe(std::move(probe)); + } + private: static data_endpoints_detail::Clock* DefaultClock() { class ClockImpl final : public data_endpoints_detail::Clock { diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/frame.h b/deps/grpc/src/core/ext/transport/chaotic_good/frame.h index 6d359976262..f3d013c1230 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/frame.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/frame.h @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -218,12 +219,22 @@ struct MessageChunkFrame final : public FrameInterface { SliceBuffer payload; }; +template +inline std::enable_if_t::value, uint32_t> +FrameMpscTokens(const T& frame) { + return frame.MakeHeader().payload_length; +} + using Frame = std::variant; +inline uint32_t FrameMpscTokens(const Frame& frame) { + return FrameMpscTokens(absl::ConvertVariantTo(frame)); +} + inline Frame CopyFrame(const Frame& frame) { return Match( frame, [](const auto& frame) -> Frame { return frame; }, diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/frame_transport.h b/deps/grpc/src/core/ext/transport/chaotic_good/frame_transport.h index d099e279e77..9befba8ccc4 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/frame_transport.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/frame_transport.h @@ -74,6 +74,10 @@ struct OutgoingFrame { std::shared_ptr call_tracer; }; +inline uint32_t FrameMpscTokens(OutgoingFrame frame) { + return FrameMpscTokens(frame.payload); +} + inline OutgoingFrame UntracedOutgoingFrame(Frame frame) { return OutgoingFrame{std::move(frame), nullptr}; } diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/message_chunker.h b/deps/grpc/src/core/ext/transport/chaotic_good/message_chunker.h index 40051aac105..285694171ee 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/message_chunker.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/message_chunker.h @@ -101,16 +101,19 @@ class MessageChunker { BeginMessageFrame begin; begin.body.set_length(message->payload()->Length()); begin.stream_id = stream_id; + uint32_t tokens = begin.MakeHeader().payload_length; return Seq( - output.Send(OutgoingFrame{std::move(begin), call_tracer}), + output.Send(OutgoingFrame{std::move(begin), call_tracer}, tokens), Loop([chunker = message_chunker_detail::PayloadChunker( max_chunk_size_, alignment_, stream_id, std::move(*message->payload())), &output, call_tracer = std::move(call_tracer)]() mutable { auto next = chunker.NextChunk(); + uint32_t tokens = FrameMpscTokens(next.frame); return Map( output.Send( - OutgoingFrame{std::move(next.frame), call_tracer}), + OutgoingFrame{std::move(next.frame), call_tracer}, + tokens), [done = next.done](StatusFlag x) -> LoopCtl { if (!done) return Continue{}; return x; @@ -121,7 +124,8 @@ class MessageChunker { MessageFrame frame; frame.message = std::move(message); frame.stream_id = stream_id; - return output.Send(OutgoingFrame{std::move(frame), nullptr}); + uint32_t tokens = FrameMpscTokens(frame); + return output.Send(OutgoingFrame{std::move(frame), nullptr}, tokens); }); } diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/scheduler.cc b/deps/grpc/src/core/ext/transport/chaotic_good/scheduler.cc new file mode 100644 index 00000000000..4754e038adf --- /dev/null +++ b/deps/grpc/src/core/ext/transport/chaotic_good/scheduler.cc @@ -0,0 +1,569 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#include "src/core/ext/transport/chaotic_good/scheduler.h" + +#include +#include +#include +#include +#include +#include + +#include "absl/log/log.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" +#include "src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h" +#include "src/core/util/shared_bit_gen.h" + +namespace grpc_core::chaotic_good { + +namespace { + +// Helper for parsing config data. +// The config data is a sequence of key=value pairs, separated by colons. +// The value may be a string, or a double, or a boolean. +// The value may be a list of enum values, separated by commas. +// The enum values are matched against the value as a string. +// If the value matches an enum value, the enum value is assigned to the output +// variable. +// If the value does not match any enum value, the config data is considered +// invalid. +class ParseConfig { + public: + ParseConfig(absl::string_view name, absl::string_view value) + : name_(name), value_(value) {} + + ParseConfig& Var(absl::string_view name, double& value) { + if (parsed_ || name != name_) return *this; + parsed_ = absl::SimpleAtod(value_, &value); + return *this; + } + + template + ParseConfig& Var( + absl::string_view name, T& value, + std::initializer_list> enum_values) { + if (parsed_ || name != name_) return *this; + for (const auto& [enum_name, enum_value] : enum_values) { + if (enum_name == value_) { + parsed_ = true; + value = enum_value; + return *this; + } + } + return *this; + } + + void Check() { + if (!parsed_) { + LOG(ERROR) << "Failed to parse " << name_ << "=" << value_; + } + } + + bool parsed() const { return parsed_; } + + private: + bool parsed_ = false; + absl::string_view name_; + absl::string_view value_; +}; + +// SimpleScheduler is a base class for schedulers that don't need to calculate +// a plan prior to allocating messages. +// This class takes care of the book-keeping and allows subclasses to just +// override ChooseChannel. +class SimpleScheduler : public Scheduler { + public: + void NewStep(double, double) override { channels_.clear(); } + + void SetConfig(absl::string_view name, absl::string_view value) override { + LOG(ERROR) << "SimpleScheduler::SetConfig: " << name << "=" << value; + } + + void AddChannel(uint32_t id, bool ready, double start_time, + double bytes_per_second) override { + channels_.emplace_back(Channel{id, ready, start_time, bytes_per_second}); + } + + void MakePlan(TcpZTraceCollector&) override { + num_ready_ = std::partition(channels_.begin(), channels_.end(), + [](const Channel& a) { return a.ready; }) - + channels_.begin(); + } + + std::optional AllocateMessage(uint64_t bytes) override { + const Channel* c = ChooseChannel(bytes); + if (c == nullptr || !c->ready) return std::nullopt; + return c->id; + } + + protected: + struct Channel { + uint32_t id; + bool ready; + double start_time; + double bytes_per_second; + }; + + virtual const Channel* ChooseChannel(uint64_t bytes) = 0; + + absl::Span channels() const { return channels_; } + absl::Span ready_channels() const { + return absl::MakeSpan(channels_).subspan(0, num_ready_); + } + absl::Span busy_channels() const { + return absl::MakeSpan(channels_).subspan(num_ready_); + } + const Channel* channel(size_t i) const { return &channels_[i]; } + size_t num_ready() const { return num_ready_; } + size_t num_channels() const { return channels_.size(); } + + std::string BaseConfig() const { return ""; } + + private: + size_t num_ready_; + std::vector channels_; +}; + +// Choose a random channel from the given list of channels. +// The weight function is (const Channel*, uint64_t bytes) -> double. +// The returned value is used to weight the channels against the dice roll. +// If the returned weight is zero or negative, the channel is not chosen. +// WeightFn is called multiple times for each channel, and must be +// deterministic. +template +const Channel* RandomChannel(absl::Span channels, uint64_t bytes, + WeightFn weight_fn) { + if (channels.size() == 0) return nullptr; + if (channels.size() == 1) return &channels[0]; + double total_weight = 0.0; + for (size_t i = 0; i < channels.size(); ++i) { + const double weight = weight_fn(&channels[i], bytes); + if (weight <= 0.0) continue; + total_weight += weight; + } + double dice_roll = absl::Uniform(SharedBitGen(), 0.0, total_weight); + for (size_t i = 0; i < channels.size(); ++i) { + const Channel* c = &channels[i]; + const double weight = weight_fn(c, bytes); + if (weight <= 0.0) continue; + if (weight >= dice_roll) return c; + dice_roll -= weight; + } + return nullptr; +} + +// RandomChoiceScheduler is a scheduler that chooses a channel at random, +// weighted by a function of the channel's state. +// It's name is "rand" and takes a single parameter "weight" which is one of: +// any_ready - choose a random ready channel +// inverse_receive_time - choose a random channel weighted by the inverse of +// its receive time +// ready_inverse_receive_time - choose a random ready channel weighted by +// the inverse of its receive time +class RandomChoiceScheduler final : public SimpleScheduler { + public: + void SetConfig(absl::string_view name, absl::string_view value) override { + ParseConfig(name, value) + .Var("weight", weight_fn_, + {{"any_ready", WeightFn::kAnyReady}, + {"inverse_receive_time", WeightFn::kInverseReceiveTime}, + {"ready_inverse_receive_time", + WeightFn::kReadyInverseReceiveTime}}) + .Check(); + } + + std::string Config() const override { + return absl::StrCat("rand:weight=", weight_fn_, BaseConfig()); + } + + private: + enum class WeightFn { + kAnyReady, + kInverseReceiveTime, + kReadyInverseReceiveTime, + }; + + template + friend void AbslStringify(Sink& sink, WeightFn weight_fn) { + switch (weight_fn) { + case WeightFn::kAnyReady: + sink.Append("any_ready"); + break; + case WeightFn::kInverseReceiveTime: + sink.Append("inverse_receive_time"); + break; + case WeightFn::kReadyInverseReceiveTime: + sink.Append("ready_inverse_receive_time"); + break; + } + } + + WeightFn weight_fn_ = WeightFn::kAnyReady; + + const Channel* ChooseChannel(uint64_t bytes) override { + switch (weight_fn_) { + case WeightFn::kAnyReady: + return RandomChannel(ready_channels(), bytes, + [](const Channel*, uint64_t) { return 1.0; }); + case WeightFn::kInverseReceiveTime: + return RandomChannel( + channels(), bytes, [](const Channel* c, uint64_t bytes) { + return 1.0 / (c->start_time + bytes / c->bytes_per_second); + }); + case WeightFn::kReadyInverseReceiveTime: + return RandomChannel( + ready_channels(), bytes, [](const Channel* c, uint64_t bytes) { + return 1.0 / (c->start_time + bytes / c->bytes_per_second); + }); + } + return nullptr; + } +}; + +// SpanScheduler is a scheduler that calculates a plan for the outstanding work +// in a single step. +// We consider when each channel will be able to deliver its next queued byte, +// and the relative delivery rates of each channel. +// As we expect channels to become ready to send we include them in the sending +// plan. +// As we're asked to allocate messages against this plan we distribute the bytes +// to channels that have sufficient allocated space in the plan to get the +// message delivered before the overall plan end time. +// This has the nice property of not needing to particularly worry about best +// placement when there's lots of work available, and focussing down to specific +// channels only when there's a small amount of work available. +class SpanScheduler : public Scheduler { + public: + void NewStep(double outstanding_bytes, double min_tokens) override; + + void SetConfig(absl::string_view name, absl::string_view value) override; + + void AddChannel(uint32_t id, bool ready, double start_time, + double bytes_per_second) override; + + // Transition: Make a plan for the outstanding work. + void MakePlan(TcpZTraceCollector& ztrace_collector) override; + + // Phase 2: Allocate messages against the plan. + // If successful, returns the id of a ready channel to assign the bytes. + // If this is not possible (all messages must go to non-ready channels), + // returns nullopt. + std::optional AllocateMessage(uint64_t bytes) override; + + protected: + struct Channel { + Channel(uint32_t id, bool ready, double start_time, double bytes_per_second) + : id(id), + ready(ready), + start_time(start_time), + bytes_per_second(bytes_per_second) {} + uint32_t id; + bool ready; + double start_time; + double bytes_per_second; + double allowed_bytes = 0.0; + }; + + absl::Span channels() const { return channels_; } + absl::Span ready_channels() const { + return absl::MakeSpan(channels_).subspan(0, num_ready_); + } + absl::Span busy_channels() const { + return absl::MakeSpan(channels_).subspan(num_ready_); + } + const Channel* channel(size_t i) const { return &channels_[i]; } + size_t num_ready() const { return num_ready_; } + size_t num_channels() const { return channels_.size(); } + + std::string BaseConfig() const { + return absl::StrCat(":step=", end_time_requested_); + } + + private: + void AdjustEndTimeForMinTokens(); + bool DistributeBytesToCollective(size_t max_channel_idx); + virtual const Channel* ChooseChannel(uint64_t bytes) = 0; + + double initial_outstanding_bytes_; + double end_time_requested_ = 1.0; + double min_tokens_; + double end_time_; + double outstanding_bytes_; + size_t num_ready_; + std::vector channels_; +}; + +void SpanScheduler::SetConfig(absl::string_view name, absl::string_view value) { + ParseConfig(name, value).Var("step", end_time_requested_).Check(); +} + +void SpanScheduler::NewStep(double outstanding_bytes, double min_tokens) { + initial_outstanding_bytes_ = outstanding_bytes; + outstanding_bytes_ = outstanding_bytes; + min_tokens_ = min_tokens; + channels_.clear(); +} + +void SpanScheduler::AddChannel(uint32_t id, bool ready, double start_time, + double bytes_per_second) { + channels_.emplace_back(id, ready, start_time, bytes_per_second); +} + +void SpanScheduler::MakePlan(TcpZTraceCollector& ztrace_collector) { + // Adjust end time to account for the min tokens. + AdjustEndTimeForMinTokens(); + // Sort channels by their start time. + std::sort(channels_.begin(), channels_.end(), + [](const Channel& a, const Channel& b) { + return a.start_time < b.start_time; + }); + // Up until we have all channels online, we distribute work amongst the ready + // channels such that they all finish at the next start time. + for (size_t i = 0; i < channels_.size(); ++i) { + if (!DistributeBytesToCollective(i)) break; + } + // Finally we partition channels into two groups: channels that are ready, + // and those that are not. + num_ready_ = std::partition(channels_.begin(), channels_.end(), + [](const Channel& a) { return a.ready; }) - + channels_.begin(); + if (num_ready_ > 1) { + std::shuffle(channels_.begin(), channels_.begin() + num_ready_, + SharedBitGen()); + } + + if (num_ready_ != 0) { + ztrace_collector.Append([this]() { + TraceWriteSchedule trace; + trace.channels.reserve(channels_.size()); + for (const auto& channel : channels_) { + trace.channels.push_back(TraceScheduledChannel{ + channel.id, channel.ready, channel.start_time, + channel.bytes_per_second, channel.allowed_bytes}); + } + std::sort(trace.channels.begin(), trace.channels.end(), + [](const TraceScheduledChannel& a, + const TraceScheduledChannel& b) { return a.id < b.id; }); + trace.outstanding_bytes = initial_outstanding_bytes_; + trace.end_time_requested = end_time_requested_; + trace.end_time_adjusted = end_time_; + trace.min_tokens = min_tokens_; + trace.num_ready = num_ready_; + return trace; + }); + } +} + +void SpanScheduler::AdjustEndTimeForMinTokens() { + double earliest_end_time = std::numeric_limits::max(); + for (Channel& channel : channels_) { + const double end_time = + channel.start_time + min_tokens_ / channel.bytes_per_second; + if (end_time < earliest_end_time) { + earliest_end_time = end_time; + } + } + end_time_ = std::max(end_time_requested_, earliest_end_time); +} + +bool SpanScheduler::DistributeBytesToCollective(size_t max_channel_idx) { + if (outstanding_bytes_ < 1.0) return false; + DCHECK_LE(max_channel_idx, channels_.size()); + // Align start times to the last channel start time. + // (we sorted these earlier) + const double start_time = channels_[max_channel_idx].start_time; + if (start_time > end_time_) return false; + // The start time of the next channel to be admitted becomes our end time + // for this step, or if we're looking at all channels finally then the overall + // end time is our end time for this step. + const double end_time = + std::min(end_time_, max_channel_idx == channels_.size() - 1 + ? end_time_ + : channels_[max_channel_idx + 1].start_time); + // Calculate the total delivery rate for the collective. + double total_delivery_rate = 0.0; + for (size_t i = 0; i <= max_channel_idx; ++i) { + total_delivery_rate += channels_[i].bytes_per_second; + } + const double bytes_deliverable = + total_delivery_rate * (end_time - start_time); + double bytes_to_deliver; + if (bytes_deliverable >= outstanding_bytes_) { + bytes_to_deliver = outstanding_bytes_; + outstanding_bytes_ = 0.0; + } else { + bytes_to_deliver = bytes_deliverable; + outstanding_bytes_ -= bytes_deliverable; + } + // Distribute the bytes to the channels in proportion to their delivery rate. + for (size_t i = 0; i <= max_channel_idx; ++i) { + channels_[i].allowed_bytes += + bytes_to_deliver * channels_[i].bytes_per_second / total_delivery_rate; + } + return true; +} + +std::optional SpanScheduler::AllocateMessage(uint64_t bytes) { + if (num_ready_ == 0) return std::nullopt; + const Channel* c = ChooseChannel(bytes); + if (c == nullptr || c >= channels_.data() + num_ready_) return std::nullopt; + Channel& chan = channels_[(c - channels_.data())]; + DCHECK(chan.ready); + DCHECK_EQ(&chan, c); + chan.allowed_bytes -= bytes; + chan.start_time += bytes / chan.bytes_per_second; + return c->id; +} + +class SpanRoundRobinScheduler final : public SpanScheduler { + public: + void NewStep(double outstanding_bytes, double min_tokens) override { + SpanScheduler::NewStep(outstanding_bytes, min_tokens); + next_ready_ = 0; + } + + void SetConfig(absl::string_view name, absl::string_view value) override { + if (!ParseConfig(name, value) + .Var("end_of_burst", end_of_burst_, + {{"random_delivery_time", EndOfBurst::kRandomDeliveryTime}, + {"random_allowed_bytes", EndOfBurst::kRandomAllowedBytes}, + {"random_ready", EndOfBurst::kRandomReady}, + {"random_channel", EndOfBurst::kRandomChannel}}) + .parsed()) { + SpanScheduler::SetConfig(name, value); + } + } + + std::string Config() const override { + return absl::StrCat("spanrr:end_of_burst=", end_of_burst_, BaseConfig()); + } + + private: + enum class EndOfBurst { + kRandomDeliveryTime, + kRandomAllowedBytes, + kRandomReady, + kRandomChannel, + }; + + template + friend void AbslStringify(Sink& sink, EndOfBurst e) { + switch (e) { + case EndOfBurst::kRandomDeliveryTime: + sink.Append("random_delivery_time"); + break; + case EndOfBurst::kRandomAllowedBytes: + sink.Append("random_allowed_bytes"); + break; + case EndOfBurst::kRandomReady: + sink.Append("random_ready"); + break; + case EndOfBurst::kRandomChannel: + sink.Append("random_channel"); + break; + } + } + + const Channel* ChooseChannel(uint64_t bytes) override { + DCHECK_LT(next_ready_, num_ready()); + // First search: we round robin through the ready channels, and choose the + // first one that has space. + const size_t first_checked = next_ready_; + do { + const Channel* c = channel(next_ready_); + next_ready_ = (next_ready_ + 1) % num_ready(); + DCHECK(c->ready); + if (c->allowed_bytes >= bytes) return c; + } while (next_ready_ != first_checked); + // Second search: no ready channel has capacity in this schedule to take + // this message. Check if there's a non-ready channel that has capacity. + // If that's the case, we're probably getting close to the end of a burst + // and we need to get selective to ensure tail latency. + for (size_t i = num_ready(); i < num_channels(); ++i) { + if (channel(i)->allowed_bytes >= bytes) { + // Yes, a non-ready channel has capacity. + // That means we can't schedule right now. + return channel(i); + } + } + // Of course, we distributed bytes in the scheduling process, not messages. + // And messages don't partition nicely in that view of the world... so when + // we get here we're about at the end of a burst and we really don't have a + // good plan for where the bytes should go. + // Luckily(*) we've tracked the start time of the next send in the + // scheduler, and we know the data rate of each channel - so now we just + // choose the channel that's going to send the message soon - with some + // randomness thrown in to de-bias the selection (light workloads need + // this). + switch (end_of_burst_) { + case EndOfBurst::kRandomDeliveryTime: + return RandomChannel( + channels(), bytes, [](const Channel* channel, double bytes) { + const double delivery_time = + channel->start_time + bytes / channel->bytes_per_second; + return 1.0 / delivery_time; + }); + case EndOfBurst::kRandomAllowedBytes: + return RandomChannel(channels(), bytes, + [](const Channel* channel, uint64_t) { + return channel->allowed_bytes; + }); + case EndOfBurst::kRandomReady: + return RandomChannel(ready_channels(), bytes, + [](const Channel*, uint64_t) { return 1.0; }); + case EndOfBurst::kRandomChannel: + return RandomChannel(channels(), bytes, + [](const Channel*, uint64_t) { return 1.0; }); + } + return nullptr; + } + + size_t next_ready_ = 0; + EndOfBurst end_of_burst_ = EndOfBurst::kRandomDeliveryTime; +}; + +} // namespace + +std::unique_ptr MakeScheduler(absl::string_view config) { + std::vector segments = absl::StrSplit(config, ':'); + auto name = segments.empty() ? "<>" : segments[0]; + std::unique_ptr scheduler; + if (name == "spanrr") { + scheduler = std::make_unique(); + } else if (name == "rand") { + scheduler = std::make_unique(); + } else { + LOG(ERROR) << "Unknown scheduler type: " << name + << " using spanrr scheduler"; + scheduler = std::make_unique(); + } + CHECK_NE(scheduler.get(), nullptr); + for (size_t i = 1; i < segments.size(); ++i) { + std::vector key_value = absl::StrSplit(segments[i], '='); + switch (key_value.size()) { + case 2: + scheduler->SetConfig(key_value[0], key_value[1]); + break; + default: + LOG(ERROR) << "Ignoring invalid scheduler config: " << segments[i]; + break; + } + } + return scheduler; +} + +} // namespace grpc_core::chaotic_good diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/scheduler.h b/deps/grpc/src/core/ext/transport/chaotic_good/scheduler.h new file mode 100644 index 00000000000..839224ce995 --- /dev/null +++ b/deps/grpc/src/core/ext/transport/chaotic_good/scheduler.h @@ -0,0 +1,68 @@ +// Copyright 2025 gRPC authors. +// +// 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. + +#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SCHEDULER_H +#define GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SCHEDULER_H + +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h" + +namespace grpc_core::chaotic_good { + +// Scheduler defines an interface for scheduling frames across multiple data +// endpoints. +// This class is used in two phases: +// Phase 1: The scheduler collects data to make decisions for a quantum. +// Transition: The scheduler makes a plan for the outstanding work. +// Phase 2: The scheduler allocates messages against its plan. +class Scheduler { + public: + virtual ~Scheduler() = default; + + virtual void SetConfig(absl::string_view name, absl::string_view value) = 0; + + // Phase 1: NewStep, then AddChannel repeatedly. + virtual void NewStep(double outstanding_bytes, double min_tokens) = 0; + + // Channels are re-added every scheduling step. + // id - indicates a persistent channel id + // ready - indicates whether the channel is ready to send frames. + // start_time - if a byte were sent now, how many seconds would it take to + // be received - includes kernel queue time, rtt, etc. + // bytes_per_second - the currently observed data rate of the channel. + virtual void AddChannel(uint32_t id, bool ready, double start_time, + double bytes_per_second) = 0; + + // Transition: Make a plan for the outstanding work. + virtual void MakePlan(TcpZTraceCollector& ztrace_collector) = 0; + + // Phase 2: Allocate messages against the plan. + // If successful, returns the id of a ready channel to assign the bytes. + // If this is not possible (all messages must go to non-ready channels), + // returns nullopt. + virtual std::optional AllocateMessage(uint64_t bytes) = 0; + + // Should only return config data. + virtual std::string Config() const = 0; +}; + +std::unique_ptr MakeScheduler(absl::string_view config); + +} // namespace grpc_core::chaotic_good + +#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHAOTIC_GOOD_SCHEDULER_H diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc b/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc index 649bec6b704..8435cf2b1eb 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc @@ -42,8 +42,11 @@ #include "src/core/lib/event_engine/channel_args_endpoint_config.h" #include "src/core/lib/event_engine/event_engine_context.h" #include "src/core/lib/event_engine/extensions/chaotic_good_extension.h" +#include "src/core/lib/event_engine/extensions/supports_fd.h" +#include "src/core/lib/event_engine/posix.h" #include "src/core/lib/event_engine/query_extensions.h" #include "src/core/lib/event_engine/resolved_address_internal.h" +#include "src/core/lib/event_engine/shim.h" #include "src/core/lib/event_engine/tcp_socket_utils.h" #include "src/core/lib/event_engine/utils.h" #include "src/core/lib/iomgr/error.h" @@ -76,6 +79,30 @@ namespace chaotic_good { namespace { const Duration kConnectionDeadline = Duration::Seconds(120); + +void LogInitFailure(Server* server, std::string what, + std::optional status) { + LOG(ERROR) << "ChaoticGoodServerListener Init failed: " << what + << " with status: " + << (status.has_value() ? status->ToString() : "no status"); + auto* server_node = server->channelz_node(); + if (server_node != nullptr) { + if (status.has_value()) { + server_node->NewTraceNode(std::move(what), ": ", *status).Commit(); + } else { + server_node->NewTraceNode(std::move(what)).Commit(); + } + } +} + +void LogInformational(Server* server, std::string what) { + VLOG(2) << "ChaoticGoodServerListener: " << what; + auto* server_node = server->channelz_node(); + if (server_node != nullptr) { + server_node->NewTraceNode(std::move(what)).Commit(); + } +} + } // namespace using grpc_event_engine::experimental::EventEngine; @@ -102,34 +129,87 @@ ChaoticGoodServerListener::~ChaoticGoodServerListener() { } } -absl::StatusOr ChaoticGoodServerListener::Bind( - grpc_event_engine::experimental::EventEngine::ResolvedAddress addr) { - if (GRPC_TRACE_FLAG_ENABLED(chaotic_good)) { - auto str = grpc_event_engine::experimental::ResolvedAddressToString(addr); - LOG(INFO) << "CHAOTIC_GOOD: Listen on " - << (str.ok() ? str->c_str() : str.status().ToString()); +absl::StatusOr< + std::unique_ptr> +ChaoticGoodServerListener::CreateListener(bool must_be_posix) { + CHECK_NE(event_engine_, nullptr); + auto* event_engine_supports_fd = + grpc_event_engine::experimental::QueryExtension< + grpc_event_engine::experimental::EventEngineSupportsFdExtension>( + event_engine_.get()); + if (must_be_posix && event_engine_supports_fd == nullptr) { + LogInitFailure(server_, + "EventEngine does not support external fd listeners", + absl::InternalError( + "EventEngine does not support external fd listeners")); + return absl::InternalError( + "EventEngine does not support external fd listeners"); + } + auto shutdown_cb = + [self = RefAsSubclass()](absl::Status status) { + if (!status.ok()) { + self->LogConnectionFailure("Server accept connection failed", status); + } + }; + if (event_engine_supports_fd != nullptr) { + grpc_event_engine::experimental::PosixEventEngineWithFdSupport:: + PosixAcceptCallback accept_cb = + [self = RefAsSubclass()]( + int listener_fd, std::unique_ptr ep, + bool is_external, MemoryAllocator, + grpc_event_engine::experimental::SliceBuffer* pending_data) { + ExecCtx exec_ctx; + LogInformational( + self->server_, + absl::StrCat("Accepting connection: ", + ResolvedAddressToString(ep->GetPeerAddress()) + .value_or("<>"))); + grpc_byte_buffer* pending_buf = nullptr; + if (pending_data != nullptr && pending_data->Length() > 0) { + pending_buf = grpc_raw_byte_buffer_create(nullptr, 0); + grpc_slice_buffer_swap(&pending_buf->data.raw.slice_buffer, + pending_data->c_slice_buffer()); + } + MutexLock lock(&self->mu_); + if (self->shutdown_) return; + self->connection_list_.emplace(MakeOrphanable( + self, std::move(ep), is_external, listener_fd, pending_buf)); + }; + return event_engine_supports_fd->CreatePosixListener( + std::move(accept_cb), std::move(shutdown_cb), + grpc_event_engine::experimental::ChannelArgsEndpointConfig(args_), + std::make_unique("chaotic_good_server_listener")); } EventEngine::Listener::AcceptCallback accept_cb = [self = RefAsSubclass()]( std::unique_ptr ep, MemoryAllocator) { ExecCtx exec_ctx; + LogInformational( + self->server_, + absl::StrCat("Accepting connection: ", + ResolvedAddressToString(ep->GetPeerAddress()) + .value_or("<>"))); MutexLock lock(&self->mu_); if (self->shutdown_) return; - self->connection_list_.emplace( - MakeOrphanable(self, std::move(ep))); + self->connection_list_.emplace(MakeOrphanable( + self, std::move(ep), false, 0, nullptr)); }; - auto shutdown_cb = [](absl::Status status) { - if (!status.ok()) { - LOG(ERROR) << "Server accept connection failed: " << status; - } - }; - CHECK_NE(event_engine_, nullptr); - auto ee_listener = event_engine_->CreateListener( + return event_engine_->CreateListener( std::move(accept_cb), std::move(shutdown_cb), grpc_event_engine::experimental::ChannelArgsEndpointConfig(args_), std::make_unique("chaotic_good_server_listener")); +} + +absl::StatusOr ChaoticGoodServerListener::Bind( + grpc_event_engine::experimental::EventEngine::ResolvedAddress addr) { + if (GRPC_TRACE_FLAG_ENABLED(chaotic_good)) { + auto str = grpc_event_engine::experimental::ResolvedAddressToString(addr); + LOG(INFO) << "CHAOTIC_GOOD: Listen on " + << (str.ok() ? str->c_str() : str.status().ToString()); + } + auto ee_listener = CreateListener(/*must_be_posix=*/false); if (!ee_listener.ok()) { - LOG(ERROR) << "Bind failed: " << ee_listener.status().ToString(); + LogInitFailure(server_, "Bind failed", ee_listener.status()); return ee_listener.status(); } ee_listener_ = std::move(ee_listener.value()); @@ -140,11 +220,62 @@ absl::StatusOr ChaoticGoodServerListener::Bind( return port_num; } +absl::Status ChaoticGoodServerListener::BindExternal(std::string addr, + const ChannelArgs& args) { + using grpc_event_engine::experimental::EventEngine; + class FdHandler final : public TcpServerFdHandler { + public: + FdHandler(RefCountedPtr listener, + grpc_event_engine::experimental::ListenerSupportsFdExtension* + listener_supports_fd) + : listener_(std::move(listener)), + listener_supports_fd_(listener_supports_fd) {} + + void Handle(int listener_fd, int fd, + grpc_byte_buffer* pending_read) override { + grpc_event_engine::experimental::SliceBuffer pending_data; + if (pending_read != nullptr) { + pending_data = + grpc_event_engine::experimental::SliceBuffer::TakeCSliceBuffer( + pending_read->data.raw.slice_buffer); + } + CHECK(GRPC_LOG_IF_ERROR("listener_handle_external_connection", + listener_supports_fd_->HandleExternalConnection( + listener_fd, fd, &pending_data))); + } + + private: + RefCountedPtr listener_; + grpc_event_engine::experimental::ListenerSupportsFdExtension* + listener_supports_fd_; + }; + auto listener = CreateListener(/*must_be_posix=*/true); + if (!listener.ok()) { + LogInitFailure(server_, "BindExternal failed", listener.status()); + return listener.status(); + } + auto* listener_supports_fd = grpc_event_engine::experimental::QueryExtension< + grpc_event_engine::experimental::ListenerSupportsFdExtension>( + listener->get()); + if (listener_supports_fd == nullptr) { + LogInitFailure(server_, + "EventEngine does not support external fd listeners", + listener.status()); + return absl::InternalError( + "EventEngine does not support external fd listeners"); + } + ee_listener_ = std::move(*listener); + TcpServerFdHandler** arg_val = args.GetPointer(addr); + *arg_val = new FdHandler(RefAsSubclass(), + listener_supports_fd); + return absl::OkStatus(); +} + absl::Status ChaoticGoodServerListener::StartListening() { CHECK(ee_listener_ != nullptr); auto status = ee_listener_->Start(); if (!status.ok()) { - LOG(ERROR) << "Start listening failed: " << status; + LogInitFailure(server_, "Start listening failed", status); } else { GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: Started listening"; } @@ -153,8 +284,10 @@ absl::Status ChaoticGoodServerListener::StartListening() { ChaoticGoodServerListener::ActiveConnection::ActiveConnection( RefCountedPtr listener, - std::unique_ptr endpoint) - : listener_(std::move(listener)) { + std::unique_ptr endpoint, bool is_external, + int listener_fd, grpc_byte_buffer* pending_data) + : listener_(std::move(listener)), + acceptor_{nullptr, 0, 0, is_external, listener_fd, pending_data} { arena_->SetContext( listener_->event_engine_.get()); handshaking_state_ = MakeRefCounted(Ref()); @@ -163,6 +296,9 @@ ChaoticGoodServerListener::ActiveConnection::ActiveConnection( ChaoticGoodServerListener::ActiveConnection::~ActiveConnection() { if (receive_settings_activity_ != nullptr) receive_settings_activity_.reset(); + if (acceptor_.pending_data != nullptr) { + grpc_byte_buffer_destroy(acceptor_.pending_data); + } } void ChaoticGoodServerListener::ActiveConnection::Orphan() { @@ -278,13 +414,16 @@ void ChaoticGoodServerListener::ActiveConnection::HandshakingState::Start( std::unique_ptr endpoint) { CoreConfiguration::Get().handshaker_registry().AddHandshakers( HANDSHAKER_SERVER, connection_->args(), nullptr, handshake_mgr_.get()); + RefCountedPtr base_node = + connection_->listener_->server_->channelz_node()->Ref(); handshake_mgr_->DoHandshake( OrphanablePtr( grpc_event_engine_endpoint_create(std::move(endpoint))), - connection_->args(), + connection_->args().SetObject(std::move(base_node)), Timestamp::Now() + connection_->listener_->data_connection_listener_ ->connection_timeout(), - nullptr, [self = Ref()](absl::StatusOr result) { + &connection_->acceptor_, + [self = Ref()](absl::StatusOr result) { self->OnHandshakeDone(std::move(result)); }); } @@ -504,24 +643,35 @@ absl::StatusOr AddChaoticGoodPort(Server* server, std::string addr, if (!IsChaoticGoodFramingLayerEnabled()) { return chaotic_good_legacy::AddLegacyChaoticGoodPort(server, addr, args); } + if (absl::StartsWith(addr, "external:")) { + auto listener = + MakeOrphanable(server, args); + if (auto status = listener->BindExternal(addr, args); !status.ok()) { + return status; + } + server->AddListener(std::move(listener)); + return -1; + } using grpc_event_engine::experimental::EventEngine; const std::string parsed_addr = URI::PercentDecode(addr); absl::StatusOr> results = std::vector(); - if (IsEventEngineDnsNonClientChannelEnabled()) { + if (IsEventEngineDnsNonClientChannelEnabled() && + !grpc_event_engine::experimental:: + EventEngineExperimentDisabledForPython()) { absl::StatusOr> ee_resolver = args.GetObjectRef()->GetDNSResolver( EventEngine::DNSResolver::ResolverOptions()); if (!ee_resolver.ok()) { - LOG(ERROR) << "Failed to resolve " << addr << ": " - << ee_resolver.status().ToString(); + LogInitFailure(server, absl::StrCat("Failed to resolve ", addr), + ee_resolver.status()); return ee_resolver.status(); } results = grpc_event_engine::experimental::LookupHostnameBlocking( ee_resolver->get(), parsed_addr, absl::StrCat(0xd20)); if (!results.ok()) { - LOG(ERROR) << "Failed to resolve " << addr << ": " - << results.status().ToString(); + LogInitFailure(server, absl::StrCat("Failed to resolve ", addr), + results.status()); return results.status(); } } else { @@ -530,8 +680,8 @@ absl::StatusOr AddChaoticGoodPort(Server* server, std::string addr, const auto resolved_or = GetDNSResolver()->LookupHostnameBlocking( parsed_addr, absl::StrCat(0xd20)); if (!resolved_or.ok()) { - LOG(ERROR) << "Failed to resolve " << addr << ": " - << resolved_or.status().ToString(); + LogInitFailure(server, absl::StrCat("Failed to resolve ", addr), + resolved_or.status()); return resolved_or.status(); } for (const auto& addr : *resolved_or) { @@ -549,6 +699,8 @@ absl::StatusOr AddChaoticGoodPort(Server* server, std::string addr, GRPC_TRACE_LOG(chaotic_good, INFO) << "BIND: " << addr_str; auto bind_result = listener->Bind(ee_addr); if (!bind_result.ok()) { + LogInitFailure(server, absl::StrCat("Failed to bind ", addr_str), + bind_result.status()); error_list.push_back( std::pair(std::move(addr_str), bind_result.status())); continue; @@ -561,6 +713,9 @@ absl::StatusOr AddChaoticGoodPort(Server* server, std::string addr, server->AddListener(std::move(listener)); } if (error_list.size() == results->size()) { + LogInitFailure(server, + absl::StrCat("Failed to bind any address for ", addr), + std::nullopt); LOG(ERROR) << "Failed to bind any address for " << addr; for (const auto& error : error_list) { LOG(ERROR) << " " << error.first << ": " << error.second; diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h b/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h index 834568a8602..153a98fffeb 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h @@ -37,6 +37,7 @@ #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_fwd.h" +#include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/promise/activity.h" #include "src/core/lib/promise/inter_activity_latch.h" #include "src/core/lib/resource_quota/memory_quota.h" @@ -73,6 +74,7 @@ class ChaoticGoodServerListener final : public Server::ListenerInterface { // Bind address to EventEngine listener. absl::StatusOr Bind( grpc_event_engine::experimental::EventEngine::ResolvedAddress addr); + absl::Status BindExternal(std::string addr, const ChannelArgs& args); absl::Status StartListening(); const ChannelArgs& args() const { return args_; } void Orphan() override; @@ -82,7 +84,8 @@ class ChaoticGoodServerListener final : public Server::ListenerInterface { ActiveConnection( RefCountedPtr listener, std::unique_ptr - endpoint); + endpoint, + bool is_external, int listener_fd, grpc_byte_buffer* pending_data); ~ActiveConnection() override; const ChannelArgs& args() const { return listener_->args(); } const ChannelArgs& handshake_result_args() const { @@ -139,6 +142,7 @@ class ChaoticGoodServerListener final : public Server::ListenerInterface { bool orphaned_ ABSL_GUARDED_BY(mu_) = false; PromiseEndpoint endpoint_; std::optional handshake_result_args_; + grpc_tcp_server_acceptor acceptor_; }; class DataConnectionListener final : public ServerConnectionFactory { @@ -205,14 +209,17 @@ class ChaoticGoodServerListener final : public Server::ListenerInterface { << "ChaoticGoodServerListener::LogConnectionFailure: " << what << ": " << (status.has_value() ? status->ToString() : "no status"); auto* server_node = server_->channelz_node(); - if (server_node != nullptr) { - server_node->AddTraceEvent( - channelz::ChannelTrace::Severity::Error, - grpc_slice_from_cpp_string(absl::StrCat( - what, ": ", - status.has_value() ? status->ToString() : "no status"))); + if (status.has_value()) { + GRPC_CHANNELZ_LOG(server_node) << what << ": " << *status; + } else { + GRPC_CHANNELZ_LOG(server_node) << what; } } + + absl::StatusOr< + std::unique_ptr> + CreateListener(bool must_be_posix); + Server* const server_; ChannelArgs args_; std::shared_ptr event_engine_; diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.cc b/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.cc index 276d63def54..baa22571863 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.cc @@ -30,6 +30,7 @@ #include "absl/random/random.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "src/core/channelz/property_list.h" #include "src/core/ext/transport/chaotic_good/frame.h" #include "src/core/ext/transport/chaotic_good/frame_header.h" #include "src/core/ext/transport/chaotic_good/frame_transport.h" @@ -140,7 +141,7 @@ auto ChaoticGoodServerTransport::StreamDispatch::SendCallInitialMetadataAndBody( frame.stream_id = stream_id; return TrySeq( outgoing_frames_.Send( - OutgoingFrame{std::move(frame), call_tracer}), + OutgoingFrame{std::move(frame), call_tracer}, 1), SendCallBody(stream_id, call_initiator, call_tracer)); }, []() { return StatusFlag(true); }); @@ -171,7 +172,7 @@ auto ChaoticGoodServerTransport::StreamDispatch::CallOutboundLoop( frame.body = ServerMetadataProtoFromGrpc(*md); frame.stream_id = stream_id; return outgoing_frames.Send( - OutgoingFrame{std::move(frame), call_tracer}); + OutgoingFrame{std::move(frame), call_tracer}, 1); })); } @@ -268,7 +269,8 @@ ChaoticGoodServerTransport::StreamDispatch::StreamDispatch( const ChannelArgs& args, FrameTransport* frame_transport, MessageChunker message_chunker, RefCountedPtr call_destination) - : ctx_(frame_transport->ctx()), + : channelz::DataSource(frame_transport->ctx()->socket_node), + ctx_(frame_transport->ctx()), call_arena_allocator_(MakeRefCounted( args.GetObject() ->memory_quota() @@ -282,9 +284,20 @@ ChaoticGoodServerTransport::StreamDispatch::StreamDispatch( ctx_->event_engine.get()); party_ = Party::Make(std::move(party_arena)); incoming_frame_spawner_ = party_->MakeSpawnSerializer(); - MpscReceiver outgoing_pipe(8); + MpscReceiver outgoing_pipe(256 * 1024 * 1024); outgoing_frames_ = outgoing_pipe.MakeSender(); frame_transport->Start(party_.get(), std::move(outgoing_pipe), Ref()); + SourceConstructed(); +} + +void ChaoticGoodServerTransport::StreamDispatch::AddData( + channelz::DataSink sink) { + party_->ExportToChannelz("transport_party", sink); + MutexLock lock(&mu_); + sink.AddData("transport_state", + channelz::PropertyList() + .Set("stream_map_size", stream_map_.size()) + .Set("last_seen_new_stream_id", last_seen_new_stream_id_)); } void ChaoticGoodServerTransport::SetCallDestination( diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.h b/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.h index 9fad40d5c7e..0f11a61589e 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/server_transport.h @@ -109,11 +109,13 @@ class ChaoticGoodServerTransport final : public ServerTransport { }; using StreamMap = absl::flat_hash_map >; - class StreamDispatch : public FrameTransportSink { + class StreamDispatch final : public FrameTransportSink, + public channelz::DataSource { public: StreamDispatch(const ChannelArgs& args, FrameTransport* frame_transport, MessageChunker message_chunker, RefCountedPtr call_destination); + ~StreamDispatch() override { SourceDestructing(); } void OnIncomingFrame(IncomingFrame incoming_frame) override; void OnFrameTransportClosed(absl::Status status) override; @@ -123,6 +125,8 @@ class ChaoticGoodServerTransport final : public ServerTransport { OrphanablePtr watcher); void StopConnectivityWatch(ConnectivityStateWatcherInterface* watcher); + void AddData(channelz::DataSink sink) override; + private: absl::Status NewStream( uint32_t stream_id, diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_header.h b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_header.h index ee53e1a9360..acc430ce5e8 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_header.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_header.h @@ -24,7 +24,9 @@ namespace grpc_core::chaotic_good { inline uint32_t DataConnectionPadding(uint32_t payload_length, uint32_t alignment) { if (payload_length % alignment == 0) return 0; - return alignment - (payload_length % alignment); + uint32_t padding = alignment - (payload_length % alignment); + DCHECK_GT(padding, 0u); + return padding; } struct TcpFrameHeader { diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.cc b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.cc index c824d86f883..6a1cca3c6d7 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.cc @@ -55,7 +55,8 @@ TcpFrameTransport::TcpFrameTransport( control_endpoint_(std::move(control_endpoint), ctx, ztrace_collector_), data_endpoints_(std::move(pending_data_endpoints), ctx, options.encode_alignment, options.decode_alignment, - ztrace_collector_, options.enable_tracing), + ztrace_collector_, options.enable_tracing, + options.scheduler_config), options_(options) { auto* transport_framing_endpoint_extension = GetTransportFramingEndpointExtension( @@ -64,10 +65,12 @@ TcpFrameTransport::TcpFrameTransport( transport_framing_endpoint_extension->SetSendFrameCallback( control_endpoint_.SecureFrameWriterCallback()); } + SourceConstructed(); } -auto TcpFrameTransport::WriteFrame(const FrameInterface& frame, - std::shared_ptr call_tracer) { +auto TcpFrameTransport::WriteFrame(MpscQueued queued_frame) { + const auto& frame = + absl::ConvertVariantTo(queued_frame->payload); FrameHeader header = frame.MakeHeader(); GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: WriteFrame to:" @@ -90,21 +93,17 @@ auto TcpFrameTransport::WriteFrame(const FrameInterface& frame, return control_endpoint_.Write(std::move(output)); }, // ... otherwise write it to a data connection - [this, header, &frame, &call_tracer]() mutable { + [this, header, &queued_frame]() mutable { SliceBuffer control_bytes; - SliceBuffer data_bytes; auto tag = next_payload_tag_; ++next_payload_tag_; TcpFrameHeader hdr{header, tag}; GRPC_TRACE_LOG(chaotic_good, INFO) << "CHAOTIC_GOOD: Send control frame " << hdr.ToString(); hdr.Serialize(control_bytes.AddTiny(TcpFrameHeader::kFrameHeaderSize)); - frame.SerializePayload(data_bytes); ztrace_collector_->Append(WriteFrameHeaderTrace{hdr}); - return DiscardResult( - Join(data_endpoints_.Write(tag, std::move(data_bytes), - std::move(call_tracer)), - control_endpoint_.Write(std::move(control_bytes)))); + data_endpoints_.Write(tag, std::move(queued_frame)); + return control_endpoint_.Write(std::move(control_bytes)); }); } @@ -115,10 +114,8 @@ auto TcpFrameTransport::WriteLoop(MpscReceiver frames) { // Get next outgoing frame. frames.Next(), // Serialize and write it out. - [self = self.get()](OutgoingFrame outgoing_frame) { - return self->WriteFrame( - absl::ConvertVariantTo(outgoing_frame.payload), - std::move(outgoing_frame.call_tracer)); + [self = self.get()](MpscQueued outgoing_frame) { + return self->WriteFrame(std::move(outgoing_frame)); }, []() -> LoopCtl { // The write failures will be caught in TrySeq and exit @@ -207,7 +204,9 @@ auto TcpFrameTransport::UntilClosed(Promise promise) { void TcpFrameTransport::Start(Party* party, MpscReceiver frames, RefCountedPtr sink) { - party->Spawn( + data_endpoints_.SetMpscProbe(frames.MakeProbe()); + auto write_party = Party::Make(party->arena()->Ref()); + write_party->Spawn( "tcp-write", [self = RefAsSubclass(), frames = std::move(frames)]() mutable { @@ -229,7 +228,8 @@ void TcpFrameTransport::Start(Party* party, MpscReceiver frames, }); })); }, - [sink, ztrace_collector = ztrace_collector_](absl::Status status) { + [sink, ztrace_collector = ztrace_collector_, + write_party = std::move(write_party)](absl::Status status) { ztrace_collector->Append(TransportError{status}); sink->OnFrameTransportClosed(std::move(status)); }); @@ -241,14 +241,14 @@ void TcpFrameTransport::Orphan() { Unref(); } -void TcpFrameTransport::AddData(channelz::DataSink& sink) { - Json::Object options; - options["encode_alignment"] = Json::FromNumber(options_.encode_alignment); - options["decode_alignment"] = Json::FromNumber(options_.decode_alignment); - options["inlined_payload_size_threshold"] = - Json::FromNumber(options_.inlined_payload_size_threshold); - options["enable_tracing"] = Json::FromBool(options_.enable_tracing); - sink.AddAdditionalInfo("chaoticGoodTcpOptions", std::move(options)); +void TcpFrameTransport::AddData(channelz::DataSink sink) { + sink.AddData("tcp_options", + channelz::PropertyList() + .Set("encode_alignment", options_.encode_alignment) + .Set("decode_alignment", options_.decode_alignment) + .Set("inlined_payload_size_threshold", + options_.inlined_payload_size_threshold) + .Set("enable_tracing", options_.enable_tracing)); } RefCountedPtr TcpFrameTransport::MakeSocketNode( diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.h b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.h index 5c518d694cc..fd772fd7d93 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_frame_transport.h @@ -42,13 +42,14 @@ class TcpFrameTransport final : public FrameTransport, uint32_t encode_alignment = 64; uint32_t decode_alignment = 64; uint32_t inlined_payload_size_threshold = 8 * 1024; + std::string scheduler_config = "spanrr"; bool enable_tracing = false; }; TcpFrameTransport(Options options, PromiseEndpoint control_endpoint, std::vector pending_data_endpoints, TransportContextPtr ctx); - ~TcpFrameTransport() override { ResetDataSource(); } + ~TcpFrameTransport() override { SourceDestructing(); } static RefCountedPtr MakeSocketNode( const ChannelArgs& args, const PromiseEndpoint& endpoint); @@ -63,11 +64,10 @@ class TcpFrameTransport final : public FrameTransport, } return DataSource::GetZTrace(name); } - void AddData(channelz::DataSink& sink) override; + void AddData(channelz::DataSink sink) override; private: - auto WriteFrame(const FrameInterface& frame, - std::shared_ptr call_tracer); + auto WriteFrame(MpscQueued queued_frame); auto WriteLoop(MpscReceiver frames); // Read frame header and payloads for control and data portions of one frame. // Resolves to StatusOr. diff --git a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h index 766dc11c55d..9d8d42ae30a 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good/tcp_ztrace_collector.h @@ -48,8 +48,6 @@ void MarkRead(bool read, Json::Object& object); struct ReadFrameHeaderTrace { TcpFrameHeader header; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& object) const { tcp_ztrace_collector_detail::MarkRead(true, object); tcp_ztrace_collector_detail::TcpFrameHeaderToJsonObject(header, object); @@ -59,8 +57,6 @@ struct ReadFrameHeaderTrace { struct ReadDataHeaderTrace { TcpDataFrameHeader header; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& object) const { tcp_ztrace_collector_detail::MarkRead(true, object); tcp_ztrace_collector_detail::TcpDataFrameHeaderToJsonObject(header, object); @@ -70,8 +66,6 @@ struct ReadDataHeaderTrace { struct WriteFrameHeaderTrace { TcpFrameHeader header; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& object) const { tcp_ztrace_collector_detail::MarkRead(false, object); tcp_ztrace_collector_detail::TcpFrameHeaderToJsonObject(header, object); @@ -83,10 +77,7 @@ struct EndpointWriteMetricsTrace { grpc_event_engine::experimental::EventEngine::Endpoint::WriteEvent write_event; std::vector> metrics; - - size_t MemoryUsage() const { - return sizeof(*this) + sizeof(metrics[0]) * metrics.size(); - } + size_t endpoint_id; void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString(absl::StrCat( @@ -96,88 +87,73 @@ struct EndpointWriteMetricsTrace { for (const auto& [name, value] : metrics) { object.emplace(name, Json::FromNumber(value)); } + object["endpoint_id"] = Json::FromNumber(endpoint_id); } }; -struct LbDecision { - struct CurrentSend { - uint64_t bytes; - double age; - }; - - uint64_t bytes; - std::optional current_send; - double current_rate; - std::optional delivery_time; - +struct TraceScheduledChannel { + uint32_t id; + bool ready; + double start_time; + double bytes_per_second; + double allowed_bytes; Json ToJson() const { - Json::Object object; - object["bytes"] = Json::FromNumber(bytes); - if (current_send.has_value()) { - object["send_size"] = Json::FromNumber(current_send->bytes); - object["send_age"] = Json::FromNumber(current_send->age); - } - object["current_rate"] = Json::FromNumber(current_rate); - if (delivery_time.has_value()) { - object["delivery_time"] = Json::FromNumber(*delivery_time); - } - return Json::FromObject(std::move(object)); + return Json::FromObject({ + {"id", Json::FromNumber(id)}, + {"ready", Json::FromBool(ready)}, + {"start_time", Json::FromNumber(start_time)}, + {"bytes_per_second", Json::FromNumber(bytes_per_second)}, + {"allowed_bytes", Json::FromNumber(allowed_bytes)}, + }); } }; -struct WriteLargeFrameHeaderTrace { - TcpDataFrameHeader data_header; - size_t chosen_endpoint; - std::vector> lb_decisions; - +struct TraceWriteSchedule { + std::vector channels; + double outstanding_bytes; + double end_time_requested; + double end_time_adjusted; + double min_tokens; + size_t num_ready; size_t MemoryUsage() const { - return sizeof(*this) + sizeof(lb_decisions[0]) * lb_decisions.size(); + return sizeof(*this) + sizeof(channels[0]) * channels.size(); } - void RenderJson(Json::Object& object) const { - tcp_ztrace_collector_detail::MarkRead(false, object); - tcp_ztrace_collector_detail::TcpDataFrameHeaderToJsonObject(data_header, - object); - Json::Array lb; - for (const auto& d : lb_decisions) { - if (d.has_value()) { - lb.emplace_back(d->ToJson()); - } else { - lb.emplace_back(Json::FromObject({})); - } + Json::Array channels; + for (const auto& c : this->channels) { + channels.emplace_back(c.ToJson()); } - object["chosen_endpoint"] = Json::FromNumber(chosen_endpoint); - object["lb_decisions"] = Json::FromArray(std::move(lb)); + object["channels"] = Json::FromArray(std::move(channels)); + object["end_time_requested"] = Json::FromNumber(end_time_requested); + object["end_time_adjusted"] = Json::FromNumber(end_time_adjusted); + object["min_tokens"] = Json::FromNumber(min_tokens); + object["outstanding_bytes"] = Json::FromNumber(outstanding_bytes); + object["num_ready"] = Json::FromNumber(num_ready); } }; -struct NoEndpointForWriteTrace { - size_t bytes; +struct WriteLargeFrameHeaderTrace { uint64_t payload_tag; - - size_t MemoryUsage() const { return sizeof(*this); } + uint64_t payload_size; + uint32_t chosen_endpoint; void RenderJson(Json::Object& object) const { - object["metadata_type"] = Json::FromString("NO_ENDPOINT_FOR_WRITE"); + object["metadata_type"] = Json::FromString("WRITE_LARGE_HEADER"); + tcp_ztrace_collector_detail::MarkRead(false, object); object["payload_tag"] = Json::FromNumber(payload_tag); - object["bytes"] = Json::FromNumber(bytes); + object["payload_size"] = Json::FromNumber(payload_size); + object["chosen_endpoint"] = Json::FromNumber(chosen_endpoint); } }; struct WriteBytesToEndpointTrace { size_t bytes; size_t endpoint_id; - bool trace; - - size_t MemoryUsage() const { return sizeof(*this); } void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString("WRITE_BYTES"); object["bytes"] = Json::FromNumber(bytes); object["endpoint_id"] = Json::FromNumber(endpoint_id); - if (trace) { - object["trace"] = Json::FromBool(true); - } } }; @@ -185,12 +161,6 @@ struct FinishWriteBytesToEndpointTrace { size_t endpoint_id; absl::Status status; - size_t MemoryUsage() const { - size_t size = sizeof(*this); - if (!status.ok()) size += status.message().size(); - return size; - } - void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString("FINISH_WRITE"); object["endpoint_id"] = Json::FromNumber(endpoint_id); @@ -201,8 +171,6 @@ struct FinishWriteBytesToEndpointTrace { struct WriteBytesToControlChannelTrace { size_t bytes; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString("WRITE_CTL_BYTES"); object["bytes"] = Json::FromNumber(bytes); @@ -212,8 +180,6 @@ struct WriteBytesToControlChannelTrace { struct FinishWriteBytesToControlChannelTrace { absl::Status status; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString("FINISH_WRITE_CTL"); object["status"] = Json::FromString(status.ToString()); @@ -224,12 +190,6 @@ template struct TransportError { absl::Status status; - size_t MemoryUsage() const { - size_t size = sizeof(*this); - if (!status.ok()) size += status.message().size(); - return size; - } - void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString(read ? "READ_ERROR" : "WRITE_ERROR"); @@ -238,8 +198,6 @@ struct TransportError { }; struct OrphanTrace { - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString("ORPHAN"); } @@ -248,8 +206,6 @@ struct OrphanTrace { struct EndpointCloseTrace { uint32_t id; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& object) const { object["metadata_type"] = Json::FromString("ENDPOINT_CLOSE"); object["endpoint_id"] = Json::FromNumber(id); @@ -258,8 +214,8 @@ struct EndpointCloseTrace { using TcpZTraceCollector = channelz::ZTraceCollector< tcp_ztrace_collector_detail::Config, ReadFrameHeaderTrace, - ReadDataHeaderTrace, WriteFrameHeaderTrace, WriteLargeFrameHeaderTrace, - EndpointWriteMetricsTrace, NoEndpointForWriteTrace, + ReadDataHeaderTrace, WriteFrameHeaderTrace, TraceWriteSchedule, + WriteLargeFrameHeaderTrace, EndpointWriteMetricsTrace, WriteBytesToEndpointTrace, FinishWriteBytesToEndpointTrace, WriteBytesToControlChannelTrace, FinishWriteBytesToControlChannelTrace, TransportError, TransportError, OrphanTrace, diff --git a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/chaotic_good_transport.h b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/chaotic_good_transport.h index 2c1d9e1d9fe..50f390413db 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/chaotic_good_transport.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/chaotic_good_transport.h @@ -31,9 +31,9 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/event_engine/event_engine_context.h" #include "src/core/lib/event_engine/tcp_socket_utils.h" +#include "src/core/lib/promise/lock_based_mpsc.h" #include "src/core/lib/promise/loop.h" #include "src/core/lib/promise/match_promise.h" -#include "src/core/lib/promise/mpsc.h" #include "src/core/lib/promise/seq.h" #include "src/core/lib/promise/try_join.h" #include "src/core/lib/promise/try_seq.h" @@ -154,7 +154,7 @@ class ChaoticGoodTransport : public RefCounted { // Common outbound loop for both client and server (these vary only over the // frame type). template - auto TransportWriteLoop(MpscReceiver& outgoing_frames) { + auto TransportWriteLoop(LockBasedMpscReceiver& outgoing_frames) { return Loop([self = Ref(), &outgoing_frames] { return TrySeq( // Get next outgoing frame. diff --git a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/client_transport.h b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/client_transport.h index baf5852836c..4b2a60054fc 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/client_transport.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/client_transport.h @@ -48,8 +48,8 @@ #include "src/core/lib/promise/for_each.h" #include "src/core/lib/promise/if.h" #include "src/core/lib/promise/inter_activity_pipe.h" +#include "src/core/lib/promise/lock_based_mpsc.h" #include "src/core/lib/promise/loop.h" -#include "src/core/lib/promise/mpsc.h" #include "src/core/lib/promise/pipe.h" #include "src/core/lib/promise/poll.h" #include "src/core/lib/promise/try_join.h" @@ -114,7 +114,7 @@ class ChaoticGoodClientTransport final : public ClientTransport { grpc_event_engine::experimental::MemoryAllocator allocator_; // Max buffer is set to 4, so that for stream writes each time it will queue // at most 2 frames. - MpscReceiver outgoing_frames_; + LockBasedMpscReceiver outgoing_frames_; Mutex mu_; uint32_t next_stream_id_ ABSL_GUARDED_BY(mu_) = 1; // Map of stream incoming server frames, key is stream_id. diff --git a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server/chaotic_good_server.cc b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server/chaotic_good_server.cc index d269668dd2b..1b74a8fc4b1 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server/chaotic_good_server.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server/chaotic_good_server.cc @@ -44,6 +44,7 @@ #include "src/core/lib/event_engine/extensions/chaotic_good_extension.h" #include "src/core/lib/event_engine/query_extensions.h" #include "src/core/lib/event_engine/resolved_address_internal.h" +#include "src/core/lib/event_engine/shim.h" #include "src/core/lib/event_engine/tcp_socket_utils.h" #include "src/core/lib/event_engine/utils.h" #include "src/core/lib/iomgr/error.h" @@ -487,7 +488,9 @@ absl::StatusOr AddLegacyChaoticGoodPort(Server* server, std::string addr, const std::string parsed_addr = URI::PercentDecode(addr); absl::StatusOr> results = std::vector(); - if (IsEventEngineDnsNonClientChannelEnabled()) { + if (IsEventEngineDnsNonClientChannelEnabled() && + !grpc_event_engine::experimental:: + EventEngineExperimentDisabledForPython()) { absl::StatusOr> ee_resolver = args.GetObjectRef()->GetDNSResolver( EventEngine::DNSResolver::ResolverOptions()); diff --git a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.cc b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.cc index 9d8412e7825..0043aadff75 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.cc +++ b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.cc @@ -132,7 +132,7 @@ auto BooleanSuccessToTransportErrorCapturingInitiator(CallInitiator initiator) { } // namespace auto ChaoticGoodServerTransport::SendFrame( - ServerFrame frame, MpscSender outgoing_frames, + ServerFrame frame, LockBasedMpscSender outgoing_frames, CallInitiator call_initiator) { // Capture the call_initiator to ensure the underlying call spine is alive // until the outgoing_frames.Send promise completes. @@ -142,7 +142,7 @@ auto ChaoticGoodServerTransport::SendFrame( } auto ChaoticGoodServerTransport::SendFrameAcked( - ServerFrame frame, MpscSender outgoing_frames, + ServerFrame frame, LockBasedMpscSender outgoing_frames, CallInitiator call_initiator) { // Capture the call_initiator to ensure the underlying call spine is alive // until the outgoing_frames.Send promise completes. @@ -152,7 +152,7 @@ auto ChaoticGoodServerTransport::SendFrameAcked( } auto ChaoticGoodServerTransport::SendCallBody( - uint32_t stream_id, MpscSender outgoing_frames, + uint32_t stream_id, LockBasedMpscSender outgoing_frames, CallInitiator call_initiator) { // Continuously send client frame with client to server messages. return ForEach(MessagesFrom(call_initiator), @@ -166,7 +166,7 @@ auto ChaoticGoodServerTransport::SendCallBody( } auto ChaoticGoodServerTransport::SendCallInitialMetadataAndBody( - uint32_t stream_id, MpscSender outgoing_frames, + uint32_t stream_id, LockBasedMpscSender outgoing_frames, CallInitiator call_initiator) { return TrySeq( // Wait for initial metadata then send it out. diff --git a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.h b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.h index 174146bc380..9fbd0e7f734 100644 --- a/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.h +++ b/deps/grpc/src/core/ext/transport/chaotic_good_legacy/server_transport.h @@ -54,8 +54,8 @@ #include "src/core/lib/promise/if.h" #include "src/core/lib/promise/inter_activity_latch.h" #include "src/core/lib/promise/inter_activity_pipe.h" +#include "src/core/lib/promise/lock_based_mpsc.h" #include "src/core/lib/promise/loop.h" -#include "src/core/lib/promise/mpsc.h" #include "src/core/lib/promise/party.h" #include "src/core/lib/promise/pipe.h" #include "src/core/lib/promise/poll.h" @@ -108,10 +108,11 @@ class ChaoticGoodServerTransport final : public ServerTransport { absl::Status NewStream(uint32_t stream_id, CallInitiator call_initiator); RefCountedPtr LookupStream(uint32_t stream_id); RefCountedPtr ExtractStream(uint32_t stream_id); - auto SendCallInitialMetadataAndBody(uint32_t stream_id, - MpscSender outgoing_frames, - CallInitiator call_initiator); - auto SendCallBody(uint32_t stream_id, MpscSender outgoing_frames, + auto SendCallInitialMetadataAndBody( + uint32_t stream_id, LockBasedMpscSender outgoing_frames, + CallInitiator call_initiator); + auto SendCallBody(uint32_t stream_id, + LockBasedMpscSender outgoing_frames, CallInitiator call_initiator); auto CallOutboundLoop(uint32_t stream_id, CallInitiator call_initiator); auto OnTransportActivityDone(absl::string_view activity); @@ -132,10 +133,11 @@ class ChaoticGoodServerTransport final : public ServerTransport { auto PushFrameIntoCall(RefCountedPtr stream, ClientEndOfStream frame); auto PushFrameIntoCall(RefCountedPtr stream, BeginMessageFrame frame); auto PushFrameIntoCall(RefCountedPtr stream, MessageChunkFrame frame); - auto SendFrame(ServerFrame frame, MpscSender outgoing_frames, + auto SendFrame(ServerFrame frame, + LockBasedMpscSender outgoing_frames, CallInitiator call_initiator); auto SendFrameAcked(ServerFrame frame, - MpscSender outgoing_frames, + LockBasedMpscSender outgoing_frames, CallInitiator call_initiator); RefCountedPtr call_destination_; @@ -143,7 +145,7 @@ class ChaoticGoodServerTransport final : public ServerTransport { const std::shared_ptr event_engine_; InterActivityLatch got_acceptor_; - MpscReceiver outgoing_frames_; + LockBasedMpscReceiver outgoing_frames_; Mutex mu_; // Map of stream incoming server frames, key is stream_id. StreamMap stream_map_ ABSL_GUARDED_BY(mu_); diff --git a/deps/grpc/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/deps/grpc/src/core/ext/transport/chttp2/client/chttp2_connector.cc index e121226a6c9..fe924487791 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -18,6 +18,7 @@ #include "src/core/ext/transport/chttp2/client/chttp2_connector.h" +#include #include #include #include @@ -28,6 +29,7 @@ #include #include +#include #include #include #include @@ -47,6 +49,14 @@ #include "src/core/credentials/transport/security_connector.h" #include "src/core/credentials/transport/transport_credentials.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#ifndef GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 +// GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 is a temporary fix to help +// some customers who are having severe memory constraints. This macro +// will not always be available and we strongly recommend anyone to avoid +// the usage of this MACRO for any other purpose. We expect to delete this +// MACRO within 8-15 months. +#include "src/core/ext/transport/chttp2/transport/http2_client_transport.h" +#endif #include "src/core/handshaker/handshaker.h" #include "src/core/handshaker/handshaker_registry.h" #include "src/core/handshaker/tcp_connect/tcp_connect_handshaker.h" @@ -55,9 +65,10 @@ #include "src/core/lib/channel/channel_args_preconditioning.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/event_engine/channel_args_endpoint_config.h" +#include "src/core/lib/event_engine/endpoint_channel_arg_wrapper.h" #include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/event_engine_shims/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel_create.h" #include "src/core/lib/surface/channel_stack_type.h" @@ -103,26 +114,41 @@ void Chttp2Connector::Connect(const Args& args, Result* result, notify_ = notify; event_engine_ = args_.channel_args.GetObject(); } - absl::StatusOr address = grpc_sockaddr_to_uri(args.address); - if (!address.ok()) { - grpc_error_handle error = GRPC_ERROR_CREATE(address.status().ToString()); - NullThenSchedClosure(DEBUG_LOCATION, ¬ify_, error); - return; + // Check if there is an endpoint in channel args. + OrphanablePtr endpoint; + auto endpoint_wrapper = args_.channel_args.GetObject< + grpc_event_engine::experimental::EndpointChannelArgWrapper>(); + if (endpoint_wrapper != nullptr) { + auto ee_endpoint = endpoint_wrapper->TakeEndpoint(); + if (ee_endpoint != nullptr) { + endpoint.reset(grpc_event_engine_endpoint_create(std::move(ee_endpoint))); + } + } + // If we weren't given the endpoint, add channel args needed by the + // TCP connect handshaker. + ChannelArgs channel_args = args_.channel_args; + if (endpoint == nullptr) { + absl::StatusOr address = grpc_sockaddr_to_uri(args.address); + if (!address.ok()) { + grpc_error_handle error = GRPC_ERROR_CREATE(address.status().ToString()); + NullThenSchedClosure(DEBUG_LOCATION, ¬ify_, error); + return; + } + channel_args = + channel_args + .Set(GRPC_ARG_TCP_HANDSHAKER_RESOLVED_ADDRESS, address.value()) + .Set(GRPC_ARG_TCP_HANDSHAKER_BIND_ENDPOINT_TO_POLLSET, 1); } - ChannelArgs channel_args = - args_.channel_args - .Set(GRPC_ARG_TCP_HANDSHAKER_RESOLVED_ADDRESS, address.value()) - .Set(GRPC_ARG_TCP_HANDSHAKER_BIND_ENDPOINT_TO_POLLSET, 1); handshake_mgr_ = MakeRefCounted(); CoreConfiguration::Get().handshaker_registry().AddHandshakers( HANDSHAKER_CLIENT, channel_args, args_.interested_parties, handshake_mgr_.get()); - handshake_mgr_->DoHandshake( - /*endpoint=*/nullptr, channel_args, args.deadline, /*acceptor=*/nullptr, - [self = RefAsSubclass()]( - absl::StatusOr result) { - self->OnHandshakeDone(std::move(result)); - }); + handshake_mgr_->DoHandshake(std::move(endpoint), channel_args, args.deadline, + /*acceptor=*/nullptr, + [self = RefAsSubclass()]( + absl::StatusOr result) { + self->OnHandshakeDone(std::move(result)); + }); } void Chttp2Connector::Shutdown(grpc_error_handle error) { @@ -143,24 +169,72 @@ void Chttp2Connector::OnHandshakeDone(absl::StatusOr result) { result_->Reset(); NullThenSchedClosure(DEBUG_LOCATION, ¬ify_, result.status()); } else if ((*result)->endpoint != nullptr) { - result_->transport = grpc_create_chttp2_transport( - (*result)->args, std::move((*result)->endpoint), true); - CHECK_NE(result_->transport, nullptr); - result_->channel_args = std::move((*result)->args); - Ref().release(); // Ref held by OnReceiveSettings() - GRPC_CLOSURE_INIT(&on_receive_settings_, OnReceiveSettings, this, - grpc_schedule_on_exec_ctx); - grpc_chttp2_transport_start_reading( - result_->transport, (*result)->read_buffer.c_slice_buffer(), - &on_receive_settings_, args_.interested_parties, nullptr); - timer_handle_ = event_engine_->RunAfter( - args_.deadline - Timestamp::Now(), - [self = RefAsSubclass()]() mutable { - ExecCtx exec_ctx; - self->OnTimeout(); - // Ensure the Chttp2Connector is deleted under an ExecCtx. - self.reset(); - }); + const bool is_callv1 = + !((*result)->args.GetBool(GRPC_ARG_USE_V3_STACK).value_or(false)); + if (is_callv1) { + result_->transport = grpc_create_chttp2_transport( + (*result)->args, std::move((*result)->endpoint), true); + CHECK_NE(result_->transport, nullptr); + result_->channel_args = std::move((*result)->args); + Ref().release(); // Ref held by OnReceiveSettings() + GRPC_CLOSURE_INIT(&on_receive_settings_, OnReceiveSettings, this, + grpc_schedule_on_exec_ctx); + grpc_chttp2_transport_start_reading( + result_->transport, (*result)->read_buffer.c_slice_buffer(), + &on_receive_settings_, args_.interested_parties, nullptr); + timer_handle_ = event_engine_->RunAfter( + args_.deadline - Timestamp::Now(), + [self = RefAsSubclass()]() mutable { + ExecCtx exec_ctx; + self->OnTimeout(); + // Ensure the Chttp2Connector is deleted under an ExecCtx. + self.reset(); + }); +#ifdef GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 + // GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 is a temporary fix to help + // some customers who are having severe memory constraints. This macro + // will not always be available and we strongly recommend anyone to avoid + // the usage of this MACRO for any other purpose. We expect to delete this + // MACRO within 8-15 months. + } +#else + } else { + // TODO(tjagtap) : [PH2][P1] : Validate this code block thoroughly once + // the ping pong test is in place. + std::unique_ptr + event_engine_endpoint = grpc_event_engine::experimental:: + grpc_take_wrapped_event_engine_endpoint( + (*result)->endpoint.release()); + if (event_engine_endpoint == nullptr) { + LOG(ERROR) << "Failed to take endpoint."; + result = GRPC_ERROR_CREATE("Failed to take endpoint."); + } + // Create the PromiseEndpoint + PromiseEndpoint promise_endpoint(std::move(event_engine_endpoint), + std::move((*result)->read_buffer)); + std::shared_ptr + event_engine_ptr = + (*result) + ->args + .GetObjectRef(); + Ref().release(); // Ref held by OnReceiveSettings() + GRPC_CLOSURE_INIT(&on_receive_settings_, OnReceiveSettings, this, + grpc_schedule_on_exec_ctx); + result_->channel_args = std::move((*result)->args); + result_->transport = new http2::Http2ClientTransport( + std::move(promise_endpoint), (*result)->args, event_engine_ptr, + &on_receive_settings_); + DCHECK_NE(result_->transport, nullptr); + timer_handle_ = event_engine_->RunAfter( + args_.deadline - Timestamp::Now(), + [self = RefAsSubclass()]() mutable { + ExecCtx exec_ctx; + self->OnTimeout(); + // Ensure the Chttp2Connector is deleted under an ExecCtx. + self.reset(); + }); + } +#endif // GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 } else { // If the handshaking succeeded but there is no endpoint, then the // handshaker may have handed off the connection to some external @@ -226,9 +300,20 @@ void Chttp2Connector::MaybeNotify(grpc_error_handle error) { absl::StatusOr CreateHttp2Channel(std::string target, const ChannelArgs& args) { +#ifdef GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 + // GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 is a temporary fix to help some + // customers who are having severe memory constraints. This macro will not + // always be available and we strongly recommend anyone to avoid the usage of + // this MACRO for any other purpose. We expect to delete this MACRO within + // 8-15 months. + const bool is_v3 = false; +#else + const bool is_v3 = IsPromiseBasedHttp2ClientTransportEnabled(); +#endif // GRPC_EXPERIMENTAL_TEMPORARILY_DISABLE_PH2 auto r = ChannelCreate( target, - args.SetObject(EndpointTransportClientChannelFactory()), + args.SetObject(EndpointTransportClientChannelFactory()) + .Set(GRPC_ARG_USE_V3_STACK, is_v3), GRPC_CLIENT_CHANNEL, nullptr); if (r.ok()) { return r->release()->c_ptr(); diff --git a/deps/grpc/src/core/ext/transport/chttp2/server/chttp2_server.cc b/deps/grpc/src/core/ext/transport/chttp2/server/chttp2_server.cc index 30ed34b2f79..60101e4e9ad 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -63,6 +63,7 @@ #include "src/core/lib/event_engine/extensions/supports_fd.h" #include "src/core/lib/event_engine/query_extensions.h" #include "src/core/lib/event_engine/resolved_address_internal.h" +#include "src/core/lib/event_engine/shim.h" #include "src/core/lib/event_engine/tcp_socket_utils.h" #include "src/core/lib/event_engine/utils.h" #include "src/core/lib/iomgr/closure.h" @@ -222,8 +223,6 @@ void NewChttp2ServerListener::ActiveConnection::HandshakingState:: void NewChttp2ServerListener::ActiveConnection::HandshakingState:: OnHandshakeDoneLocked(absl::StatusOr result) { - OrphanablePtr handshaking_state_ref; - RefCountedPtr handshake_mgr; // If the handshaking succeeded but there is no endpoint, then the // handshaker may have handed off the connection to some external // code, so we can just clean up here without creating a transport. @@ -234,7 +233,7 @@ void NewChttp2ServerListener::ActiveConnection::HandshakingState:: std::move((*result)->endpoint), false) ->Ref(); grpc_error_handle channel_init_err = - connection_->listener_state_->server()->SetupTransport( + connection_->listener_state_->SetupTransport( transport.get(), accepting_pollset_, (*result)->args); if (channel_init_err.ok()) { // Use notify_on_receive_settings callback to enforce the @@ -245,7 +244,7 @@ void NewChttp2ServerListener::ActiveConnection::HandshakingState:: GRPC_CLOSURE_INIT(&on_receive_settings_, OnReceiveSettings, this, grpc_schedule_on_exec_ctx); grpc_closure* on_close = &connection_->on_close_; - // Refs helds by OnClose() + // Refs held by OnClose() connection_->Ref().release(); grpc_chttp2_transport_start_reading( transport.get(), (*result)->read_buffer.c_slice_buffer(), @@ -649,7 +648,9 @@ absl::StatusOr Chttp2ServerAddPort(Server* server, const char* addr, resolved = grpc_resolve_vsock_address(parsed_addr_unprefixed); GRPC_RETURN_IF_ERROR(resolved.status()); } else { - if (IsEventEngineDnsNonClientChannelEnabled()) { + if (IsEventEngineDnsNonClientChannelEnabled() && + !grpc_event_engine::experimental:: + EventEngineExperimentDisabledForPython()) { absl::StatusOr> ee_resolver = args.GetObjectRef()->GetDNSResolver( EventEngine::DNSResolver::ResolverOptions()); diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 73c3f4b887c..02608aa03eb 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -16,6 +16,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include #include #include #include @@ -55,8 +56,10 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" +#include "absl/time/time.h" #include "src/core/call/metadata_batch.h" #include "src/core/call/metadata_info.h" +#include "src/core/channelz/property_list.h" #include "src/core/config/config_vars.h" #include "src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h" #include "src/core/ext/transport/chttp2/transport/flow_control.h" @@ -66,6 +69,7 @@ #include "src/core/ext/transport/chttp2/transport/frame_security.h" #include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" #include "src/core/ext/transport/chttp2/transport/http2_settings.h" +#include "src/core/ext/transport/chttp2/transport/http2_stats_collector.h" #include "src/core/ext/transport/chttp2/transport/http2_status.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/ext/transport/chttp2/transport/legacy_frame.h" @@ -106,6 +110,8 @@ #include "src/core/telemetry/default_tcp_tracer.h" #include "src/core/telemetry/stats.h" #include "src/core/telemetry/stats_data.h" +#include "src/core/telemetry/tcp_tracer.h" +#include "src/core/transport/auth_context.h" #include "src/core/util/bitset.h" #include "src/core/util/crash.h" #include "src/core/util/debug_location.h" @@ -152,7 +158,8 @@ static bool g_default_server_keepalive_permit_without_calls = false; // forward declarations of various callbacks that we'll build closures around static void write_action_begin_locked( grpc_core::RefCountedPtr, grpc_error_handle error); -static void write_action(grpc_chttp2_transport* t); +static void write_action(grpc_chttp2_transport* t, + std::vector tcp_call_tracers); static void write_action_end(grpc_core::RefCountedPtr, grpc_error_handle error); static void write_action_end_locked( @@ -232,9 +239,14 @@ namespace { using EventEngine = ::grpc_event_engine::experimental::EventEngine; using TaskHandle = ::grpc_event_engine::experimental::EventEngine::TaskHandle; using grpc_core::http2::Http2ErrorCode; +using WriteMetric = + ::grpc_event_engine::experimental::EventEngine::Endpoint::WriteMetric; +using WriteEventSink = + ::grpc_event_engine::experimental::EventEngine::Endpoint::WriteEventSink; +using WriteEvent = + ::grpc_event_engine::experimental::EventEngine::Endpoint::WriteEvent; grpc_core::WriteTimestampsCallback g_write_timestamps_callback = nullptr; -grpc_core::CopyContextFn g_get_copied_context_fn = nullptr; } // namespace namespace grpc_core { @@ -283,16 +295,10 @@ void GrpcHttp2SetWriteTimestampsCallback(WriteTimestampsCallback fn) { g_write_timestamps_callback = fn; } -void GrpcHttp2SetCopyContextFn(CopyContextFn fn) { - g_get_copied_context_fn = fn; -} - WriteTimestampsCallback GrpcHttp2GetWriteTimestampsCallback() { return g_write_timestamps_callback; } -CopyContextFn GrpcHttp2GetCopyContextFn() { return g_get_copied_context_fn; } - // For each entry in the passed ContextList, it executes the function set using // GrpcHttp2SetWriteTimestampsCallback method with each context in the list // and \a ts. It also deletes/frees up the passed ContextList after this @@ -355,20 +361,15 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { cancel_pings(this, GRPC_ERROR_CREATE("Transport destroyed")); - event_engine.reset(); - if (channelz_socket != nullptr) { channelz_socket.reset(); } + event_engine.reset(); + grpc_slice_buffer_destroy(&qbuf); - grpc_error_handle error = GRPC_ERROR_CREATE("Transport destroyed"); - // ContextList::Execute follows semantics of a callback function and does not - // take a ref on error - if (context_list != nullptr) { - grpc_core::ForEachContextListEntryExecute(context_list, nullptr, error); - } + delete context_list; context_list = nullptr; grpc_slice_buffer_destroy(&read_buffer); @@ -472,27 +473,6 @@ static void read_channel_args(grpc_chttp2_transport* t, t->max_requests_per_read = 32; } - if (channel_args.GetBool(GRPC_ARG_ENABLE_CHANNELZ) - .value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) { - t->channelz_socket = - grpc_core::MakeRefCounted( - std::string(grpc_endpoint_get_local_address(t->ep.get())), - std::string(t->peer_string.as_string_view()), - absl::StrCat(t->GetTransportName(), " ", - t->peer_string.as_string_view()), - channel_args - .GetObjectRef()); - // Checks channelz_socket, so must be initialized after. - t->channelz_data_source = - std::make_unique(t); - auto epte = QueryExtension( - grpc_event_engine::experimental::grpc_get_wrapped_event_engine_endpoint( - t->ep.get())); - if (epte != nullptr) { - epte->SetSocketNode(t->channelz_socket); - } - } - t->ack_pings = channel_args.GetBool("grpc.http2.ack_pings").value_or(true); t->allow_tarpit = @@ -535,6 +515,7 @@ static void read_channel_args(grpc_chttp2_transport* t, channel_args.GetInt(GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES).value_or(-1); if (value >= 0) { t->settings.mutable_local().SetInitialWindowSize(value); + t->flow_control.set_target_initial_window_size(value); } value = channel_args.GetInt(GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY).value_or(-1); if (value >= 0) { @@ -581,84 +562,87 @@ static void init_keepalive_pings_if_enabled_locked( } void grpc_chttp2_transport::ChannelzDataSource::AddData( - grpc_core::channelz::DataSink& sink) { - grpc_core::Notification n; - transport_->event_engine->Run([t = transport_->Ref(), &n, &sink]() { + grpc_core::channelz::DataSink sink) { + transport_->event_engine->Run([t = transport_->Ref(), + sink = std::move(sink)]() mutable { grpc_core::ExecCtx exec_ctx; t->combiner->Run( - grpc_core::NewClosure([t, &n, &sink](grpc_error_handle) { + grpc_core::NewClosure([t, sink = std::move(sink)]( + grpc_error_handle) mutable { Json::Object http2_info; - http2_info["flowControl"] = - Json::FromObject(t->flow_control.stats().ToJsonObject()); - Json::Object misc; - misc["maxRequestsPerRead"] = - Json::FromNumber(static_cast(t->max_requests_per_read)); - misc["nextStreamId"] = Json::FromNumber(t->next_stream_id); - misc["lastNewStreamId"] = Json::FromNumber(t->last_new_stream_id); - misc["numIncomingStreamsBeforeSettingsAck"] = - Json::FromNumber(t->num_incoming_streams_before_settings_ack); - misc["pingAckCount"] = - Json::FromNumber(static_cast(t->ping_ack_count)); - misc["allowTarpit"] = Json::FromBool(t->allow_tarpit); - if (t->allow_tarpit) { - misc["minTarpitDurationMs"] = - Json::FromNumber(t->min_tarpit_duration_ms); - misc["maxTarpitDurationMs"] = - Json::FromNumber(t->max_tarpit_duration_ms); - } - misc["keepaliveTime"] = - Json::FromString(t->keepalive_time.ToJsonString()); - misc["nextAdjustedKeepaliveTimestamp"] = - Json::FromString((t->next_adjusted_keepalive_timestamp - - grpc_core::Timestamp::Now()) - .ToJsonString()); - misc["numMessagesInNextWrite"] = - Json::FromNumber(t->num_messages_in_next_write); - misc["numPendingInducedFrames"] = - Json::FromNumber(t->num_pending_induced_frames); - misc["writeBufferSize"] = Json::FromNumber(t->write_buffer_size); - misc["readingPausedOnPendingInducedFrames"] = - Json::FromBool(t->reading_paused_on_pending_induced_frames); - misc["enablePreferredRxCryptoFrameAdvertisement"] = - Json::FromBool(t->enable_preferred_rx_crypto_frame_advertisement); - misc["keepalivePermitWithoutCalls"] = - Json::FromBool(t->keepalive_permit_without_calls); - misc["bdpPingBlocked"] = Json::FromBool(t->bdp_ping_blocked); - misc["bdpPingStarted"] = Json::FromBool(t->bdp_ping_started); - misc["ackPings"] = Json::FromBool(t->ack_pings); - misc["keepaliveIncomingDataWanted"] = - Json::FromBool(t->keepalive_incoming_data_wanted); - misc["maxConcurrentStreamsOverloadProtection"] = - Json::FromBool(t->max_concurrent_streams_overload_protection); - misc["maxConcurrentStreamsRejectOnClient"] = - Json::FromBool(t->max_concurrent_streams_reject_on_client); - misc["pingOnRstStreamPercent"] = - Json::FromNumber(t->ping_on_rst_stream_percent); - misc["lastWindowUpdateAge"] = Json::FromString( - (grpc_core::Timestamp::Now() - t->last_window_update_time) - .ToJsonString()); - http2_info["misc"] = Json::FromObject(std::move(misc)); - http2_info["settings"] = Json::FromObject(t->settings.ToJsonObject()); - sink.AddAdditionalInfo("http2", std::move(http2_info)); - std::vector> - children; - children.reserve(t->stream_map.size()); - for (auto [id, stream] : t->stream_map) { - if (stream->channelz_call_node == nullptr) { - stream->channelz_call_node = - grpc_core::MakeRefCounted( - absl::StrCat("chttp2 ", - t->is_client ? "client" : "server", - " stream ", stream->id)); - } - children.push_back(stream->channelz_call_node); - } - sink.AddChildObjects(std::move(children)); - n.Notify(); + sink.AddData( + "http2", + grpc_core::channelz::PropertyList() + .Set("max_requests_per_read", t->max_requests_per_read) + .Set("next_stream_id", t->next_stream_id) + .Set("last_new_stream_id", t->last_new_stream_id) + .Set("num_incoming_streams_before_settings_ack", + t->num_incoming_streams_before_settings_ack) + .Set("ping_ack_count", t->ping_ack_count) + .Set("allow_tarpit", t->allow_tarpit) + .Set("min_tarpit_duration_ms", t->min_tarpit_duration_ms) + .Set("max_tarpit_duration_ms", t->max_tarpit_duration_ms) + .Set("keepalive_time", t->keepalive_time) + .Set("next_adjusted_keepalive_timestamp", + t->next_adjusted_keepalive_timestamp) + .Set("num_messages_in_next_write", + t->num_messages_in_next_write) + .Set("num_pending_induced_frames", + t->num_pending_induced_frames) + .Set("write_buffer_size", t->write_buffer_size) + .Set("reading_paused_on_pending_induced_frames", + t->reading_paused_on_pending_induced_frames) + .Set("enable_preferred_rx_crypto_frame_advertisement", + t->enable_preferred_rx_crypto_frame_advertisement) + .Set("keepalive_permit_without_calls", + t->keepalive_permit_without_calls) + .Set("bdp_ping_blocked", t->bdp_ping_blocked) + .Set("bdp_ping_started", t->bdp_ping_started) + .Set("ack_pings", t->ack_pings) + .Set("keepalive_incoming_data_wanted", + t->keepalive_incoming_data_wanted) + .Set("max_concurrent_streams_overload_protection", + t->max_concurrent_streams_overload_protection) + .Set("max_concurrent_streams_reject_on_client", + t->max_concurrent_streams_reject_on_client) + .Set("ping_on_rst_stream_percent", + t->ping_on_rst_stream_percent) + .Set("last_window_update", t->last_window_update_time) + .Set("settings", t->settings.ChannelzProperties()) + .Set("flow_control", + t->flow_control.stats().ChannelzProperties()) + .Set("ping_rate_policy", + t->ping_rate_policy.ChannelzProperties()) + .Set("ping_callbacks", t->ping_callbacks.ChannelzProperties()) + .Set("goaway_error", t->goaway_error) + .Set("sent_goaway_state", + [t]() { + switch (t->sent_goaway_state) { + case GRPC_CHTTP2_NO_GOAWAY_SEND: + return "none"; + case GRPC_CHTTP2_GRACEFUL_GOAWAY: + return "graceful"; + case GRPC_CHTTP2_FINAL_GOAWAY_SEND_SCHEDULED: + return "final_scheduled"; + case GRPC_CHTTP2_FINAL_GOAWAY_SENT: + return "final_sent"; + } + return "unknown"; + }()) + .Set("write_state", [t]() { + switch (t->write_state) { + case GRPC_CHTTP2_WRITE_STATE_IDLE: + return "idle"; + case GRPC_CHTTP2_WRITE_STATE_WRITING: + return "writing"; + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: + return "writing_with_more"; + } + return "unknown"; + }())); }), absl::OkStatus()); }); - n.WaitForNotification(); } std::unique_ptr @@ -798,6 +782,10 @@ grpc_chttp2_transport::grpc_chttp2_transport( grpc_core::test_only_init_callback(); } + grpc_auth_context* auth_context = channel_args.GetObject(); + http2_stats = grpc_core::CreateHttp2StatsCollector(auth_context); + hpack_parser.hpack_table()->SetHttp2StatsCollector(http2_stats); + #ifdef GRPC_POSIX_SOCKET_TCP closure_barrier_may_cover_write = grpc_event_engine_run_in_background() && @@ -805,6 +793,26 @@ grpc_chttp2_transport::grpc_chttp2_transport( ? 0 : CLOSURE_BARRIER_MAY_COVER_WRITE; #endif + + if (channel_args.GetBool(GRPC_ARG_ENABLE_CHANNELZ) + .value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) { + channelz_socket = + grpc_core::MakeRefCounted( + std::string(grpc_endpoint_get_local_address(ep.get())), + std::string(peer_string.as_string_view()), + absl::StrCat(GetTransportName(), " ", peer_string.as_string_view()), + channel_args + .GetObjectRef()); + // Checks channelz_socket, so must be initialized after. + channelz_data_source = + std::make_unique(this); + auto epte = QueryExtension( + grpc_event_engine::experimental::grpc_get_wrapped_event_engine_endpoint( + ep.get())); + if (epte != nullptr) { + epte->SetSocketNode(channelz_socket); + } + } } static void destroy_transport_locked(void* tp, grpc_error_handle /*error*/) { @@ -816,6 +824,7 @@ static void destroy_transport_locked(void* tp, grpc_error_handle /*error*/) { } void grpc_chttp2_transport::Orphan() { + channelz_data_source.reset(); combiner->Run(GRPC_CLOSURE_CREATE(destroy_transport_locked, this, nullptr), absl::OkStatus()); } @@ -1140,7 +1149,7 @@ static void write_action_begin_locked( r.partial ? GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE : GRPC_CHTTP2_WRITE_STATE_WRITING, begin_writing_desc(r.partial)); - write_action(t.get()); + write_action(t.get(), std::move(r.tcp_call_tracers)); if (t->reading_paused_on_pending_induced_frames) { CHECK_EQ(t->num_pending_induced_frames, 0u); // We had paused reading, because we had many induced frames (SETTINGS @@ -1159,7 +1168,9 @@ static void write_action_begin_locked( } } -static void write_action(grpc_chttp2_transport* t) { +static void write_action( + grpc_chttp2_transport* t, + std::vector tcp_call_tracers) { void* cl = t->context_list; if (!t->context_list->empty()) { // Transfer the ownership of the context list to the endpoint and create and @@ -1174,6 +1185,7 @@ static void write_action(grpc_chttp2_transport* t) { } // Choose max_frame_size as the preferred rx crypto frame size indicated by // the peer. + grpc_event_engine::experimental::EventEngine::Endpoint::WriteArgs args; int max_frame_size = t->settings.peer().preferred_receive_crypto_message_size(); // Note: max frame size is 0 if the remote peer does not support adjusting the @@ -1181,6 +1193,42 @@ static void write_action(grpc_chttp2_transport* t) { if (max_frame_size == 0) { max_frame_size = INT_MAX; } + args.set_max_frame_size(max_frame_size); + args.SetDeprecatedAndDiscouragedGoogleSpecificPointer(cl); + if (!tcp_call_tracers.empty()) { + EventEngine::Endpoint* ee_ep = + grpc_event_engine::experimental::grpc_get_wrapped_event_engine_endpoint( + t->ep.get()); + if (ee_ep != nullptr) { + auto telemetry_info = ee_ep->GetTelemetryInfo(); + if (telemetry_info != nullptr) { + auto metrics_set = telemetry_info->GetFullMetricsSet(); + args.set_metrics_sink(WriteEventSink( + std::move(metrics_set), + {WriteEvent::kSendMsg, WriteEvent::kScheduled, WriteEvent::kSent, + WriteEvent::kAcked}, + [tcp_call_tracers = std::move(tcp_call_tracers), + telemetry_info = std::move(telemetry_info)]( + WriteEvent event, absl::Time timestamp, + std::vector metrics) { + std::vector tcp_metrics; + tcp_metrics.reserve(metrics.size()); + for (auto& metric : metrics) { + auto name = telemetry_info->GetMetricName(metric.key); + if (name.has_value()) { + tcp_metrics.push_back( + grpc_core::TcpCallTracer::TcpEventMetric{name.value(), + metric.value}); + } + } + for (auto& tracer : tcp_call_tracers) { + tracer.tcp_call_tracer->RecordEvent( + event, timestamp, tracer.byte_offset, tcp_metrics); + } + })); + } + } + } GRPC_TRACE_LOG(http2_ping, INFO) << (t->is_client ? "CLIENT" : "SERVER") << "[" << t << "]: Write " << t->outbuf.Length() << " bytes"; @@ -1190,7 +1238,7 @@ static void write_action(grpc_chttp2_transport* t) { grpc_endpoint_write(t->ep.get(), t->outbuf.c_slice_buffer(), grpc_core::InitTransportClosure( t->Ref(), &t->write_action_end_locked), - cl, max_frame_size); + std::move(args)); } static void write_action_end(grpc_core::RefCountedPtr t, @@ -1560,7 +1608,7 @@ static void send_message_locked( grpc_transport_stream_op_batch_payload* op_payload, grpc_chttp2_transport* t, grpc_closure* on_complete) { t->num_messages_in_next_write++; - grpc_core::global_stats().IncrementHttp2SendMessageSize( + t->http2_stats->IncrementHttp2SendMessageSize( op->payload->send_message.send_message->Length()); on_complete->next_data.scratch |= t->closure_barrier_may_cover_write; s->send_message_finished = add_closure_barrier(op->on_complete); @@ -2400,8 +2448,7 @@ void grpc_chttp2_cancel_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s, // sent headers yet (still in "idle" state). Note that since we have // marked the stream closed above, we won't be writing to it // anymore. - if (grpc_core::IsRstStreamFixEnabled() && t->is_client && - !sent_initial_metadata) { + if (t->is_client && !sent_initial_metadata) { return; } grpc_chttp2_add_rst_stream_to_next_write( diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.h index b3737431744..d583b82b377 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -79,13 +79,10 @@ void TestOnlyGlobalHttp2TransportDisableTransientFailureStateNotification( typedef void (*WriteTimestampsCallback)(void*, Timestamps*, grpc_error_handle error); -typedef void* (*CopyContextFn)(Arena*); void GrpcHttp2SetWriteTimestampsCallback(WriteTimestampsCallback fn); -void GrpcHttp2SetCopyContextFn(CopyContextFn fn); WriteTimestampsCallback GrpcHttp2GetWriteTimestampsCallback(); -CopyContextFn GrpcHttp2GetCopyContextFn(); // Interprets the passed arg as a ContextList type and for each entry in the // passed ContextList, it executes the function set using diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.cc index 8a2300dac4b..9d62922a30e 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.cc @@ -1,4 +1,4 @@ -// Copyright 2022 gRPC authors. +// Copyright 2023 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -2134,839 +2134,872 @@ const uint8_t* const HuffDecoderCommon::table10_outer_[128] = { table8_0_outer_, table8_0_outer_, table8_0_outer_, table8_0_outer_, table8_10_outer_, table8_10_outer_, table8_10_outer_, table10_127_outer_, }; -const uint8_t HuffDecoderCommon::table11_0_emit_[7] = {0x30, 0x30, 0x31, 0x30, - 0x32, 0x30, 0x61}; -const uint16_t HuffDecoderCommon::table11_0_inner_[5] = {0x0000, 0x0001, 0x0005, - 0x000d, 0x0015}; -const uint8_t HuffDecoderCommon::table11_1_emit_[8] = {0x30, 0x63, 0x30, 0x65, - 0x30, 0x69, 0x30, 0x6f}; -const uint16_t HuffDecoderCommon::table11_1_inner_[5] = {0x0000, 0x0001, 0x0009, - 0x0011, 0x0019}; -const uint8_t HuffDecoderCommon::table11_2_emit_[12] = { +const uint8_t HuffDecoderCommon::table1_0_emit_[7] = {0x30, 0x30, 0x31, 0x30, + 0x32, 0x30, 0x61}; +const uint16_t HuffDecoderCommon::table1_0_inner_[4] = {0x000a, 0x004a, 0x00ca, + 0x014a}; +const uint8_t HuffDecoderCommon::table1_0_outer_[64] = { + 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; +const uint8_t HuffDecoderCommon::table1_1_emit_[8] = {0x30, 0x63, 0x30, 0x65, + 0x30, 0x69, 0x30, 0x6f}; +const uint16_t HuffDecoderCommon::table1_1_inner_[4] = {0x000a, 0x008a, 0x010a, + 0x018a}; +const uint8_t HuffDecoderCommon::table1_2_emit_[12] = { 0x30, 0x73, 0x30, 0x74, 0x30, 0x20, 0x30, 0x25, 0x30, 0x2d, 0x30, 0x2e}; -const uint16_t HuffDecoderCommon::table11_2_inner_[7] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029}; -const uint8_t HuffDecoderCommon::table11_2_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, - 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6}; -const uint8_t HuffDecoderCommon::table11_3_emit_[16] = { +const uint16_t HuffDecoderCommon::table1_2_inner_[6] = {0x000a, 0x008a, 0x010b, + 0x018b, 0x020b, 0x028b}; +const uint8_t HuffDecoderCommon::table1_2_outer_[64] = { + 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, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5}; +const uint8_t HuffDecoderCommon::table1_3_emit_[16] = { 0x30, 0x2f, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x39}; -const uint8_t HuffDecoderCommon::table11_4_emit_[16] = { +const uint16_t HuffDecoderCommon::table1_3_inner_[8] = { + 0x000b, 0x008b, 0x010b, 0x018b, 0x020b, 0x028b, 0x030b, 0x038b}; +const uint8_t HuffDecoderCommon::table1_3_outer_[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7}; +const uint8_t HuffDecoderCommon::table1_4_emit_[16] = { 0x30, 0x3d, 0x30, 0x41, 0x30, 0x5f, 0x30, 0x62, 0x30, 0x64, 0x30, 0x66, 0x30, 0x67, 0x30, 0x68}; -const uint8_t HuffDecoderCommon::table11_5_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_5_emit_[20] = { 0x30, 0x6c, 0x30, 0x6d, 0x30, 0x6e, 0x30, 0x70, 0x30, 0x72, 0x30, 0x75, 0x30, 0x3a, 0x30, 0x42, 0x30, 0x43, 0x30, 0x44}; -const uint16_t HuffDecoderCommon::table11_5_inner_[11] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, - 0x0029, 0x0031, 0x0039, 0x0041, 0x0049}; -const uint8_t HuffDecoderCommon::table11_5_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10}; -const uint8_t HuffDecoderCommon::table11_6_emit_[32] = { +const uint16_t HuffDecoderCommon::table1_5_inner_[10] = { + 0x000b, 0x008b, 0x010b, 0x018b, 0x020b, + 0x028b, 0x030c, 0x038c, 0x040c, 0x048c}; +const uint8_t HuffDecoderCommon::table1_5_outer_[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9}; +const uint8_t HuffDecoderCommon::table1_6_emit_[32] = { 0x30, 0x45, 0x30, 0x46, 0x30, 0x47, 0x30, 0x48, 0x30, 0x49, 0x30, 0x4a, 0x30, 0x4b, 0x30, 0x4c, 0x30, 0x4d, 0x30, 0x4e, 0x30, 0x4f, 0x30, 0x50, 0x30, 0x51, 0x30, 0x52, 0x30, 0x53, 0x30, 0x54}; -const uint16_t HuffDecoderCommon::table11_6_inner_[17] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, 0x0039, - 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, 0x0079}; -const uint8_t HuffDecoderCommon::table11_6_outer_[64] = { - 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, - 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, - 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16}; -const uint8_t HuffDecoderCommon::table11_7_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_6_inner_[16] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, + 0x040c, 0x048c, 0x050c, 0x058c, 0x060c, 0x068c, 0x070c, 0x078c}; +const uint8_t HuffDecoderCommon::table1_6_outer_[64] = { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15}; +const uint8_t HuffDecoderCommon::table1_7_emit_[36] = { 0x30, 0x55, 0x30, 0x56, 0x30, 0x57, 0x30, 0x59, 0x30, 0x6a, 0x30, 0x6b, 0x30, 0x71, 0x30, 0x76, 0x30, 0x77, 0x30, 0x78, 0x30, 0x79, 0x30, 0x7a, 0x30, 0x26, 0x30, 0x2a, 0x30, 0x2c, 0x30, 0x3b, 0x30, 0x58, 0x30, 0x5a}; -const uint16_t HuffDecoderCommon::table11_7_inner_[20] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, - 0x0069, 0x0071, 0x0079, 0x0081, 0x0089, 0x0002}; -const uint8_t HuffDecoderCommon::table11_7_outer_[64] = { - 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, - 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, - 0, 0, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, 0, 17, 0, 18, 0, 0, 0, 19}; -const uint8_t HuffDecoderCommon::table11_8_emit_[7] = {0x31, 0x30, 0x31, 0x31, - 0x32, 0x31, 0x61}; -const uint16_t HuffDecoderCommon::table11_8_inner_[5] = {0x0000, 0x0001, 0x0009, - 0x000d, 0x0015}; -const uint8_t HuffDecoderCommon::table11_9_emit_[8] = {0x31, 0x63, 0x31, 0x65, - 0x31, 0x69, 0x31, 0x6f}; -const uint8_t HuffDecoderCommon::table11_10_emit_[12] = { +const uint16_t HuffDecoderCommon::table1_7_inner_[19] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x040c, 0x048c, 0x050c, 0x058c, 0x060d, 0x068d, + 0x070d, 0x078d, 0x080d, 0x088d, 0x0015}; +const uint8_t HuffDecoderCommon::table1_7_outer_[64] = { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18}; +const uint8_t HuffDecoderCommon::table1_8_emit_[7] = {0x31, 0x30, 0x31, 0x31, + 0x32, 0x31, 0x61}; +const uint16_t HuffDecoderCommon::table1_8_inner_[4] = {0x000a, 0x008a, 0x00ca, + 0x014a}; +const uint8_t HuffDecoderCommon::table1_9_emit_[8] = {0x31, 0x63, 0x31, 0x65, + 0x31, 0x69, 0x31, 0x6f}; +const uint8_t HuffDecoderCommon::table1_10_emit_[12] = { 0x31, 0x73, 0x31, 0x74, 0x31, 0x20, 0x31, 0x25, 0x31, 0x2d, 0x31, 0x2e}; -const uint8_t HuffDecoderCommon::table11_11_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_11_emit_[16] = { 0x31, 0x2f, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, 0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39}; -const uint8_t HuffDecoderCommon::table11_12_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_12_emit_[16] = { 0x31, 0x3d, 0x31, 0x41, 0x31, 0x5f, 0x31, 0x62, 0x31, 0x64, 0x31, 0x66, 0x31, 0x67, 0x31, 0x68}; -const uint8_t HuffDecoderCommon::table11_13_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_13_emit_[20] = { 0x31, 0x6c, 0x31, 0x6d, 0x31, 0x6e, 0x31, 0x70, 0x31, 0x72, 0x31, 0x75, 0x31, 0x3a, 0x31, 0x42, 0x31, 0x43, 0x31, 0x44}; -const uint8_t HuffDecoderCommon::table11_14_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_14_emit_[32] = { 0x31, 0x45, 0x31, 0x46, 0x31, 0x47, 0x31, 0x48, 0x31, 0x49, 0x31, 0x4a, 0x31, 0x4b, 0x31, 0x4c, 0x31, 0x4d, 0x31, 0x4e, 0x31, 0x4f, 0x31, 0x50, 0x31, 0x51, 0x31, 0x52, 0x31, 0x53, 0x31, 0x54}; -const uint8_t HuffDecoderCommon::table11_15_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_15_emit_[36] = { 0x31, 0x55, 0x31, 0x56, 0x31, 0x57, 0x31, 0x59, 0x31, 0x6a, 0x31, 0x6b, 0x31, 0x71, 0x31, 0x76, 0x31, 0x77, 0x31, 0x78, 0x31, 0x79, 0x31, 0x7a, 0x31, 0x26, 0x31, 0x2a, 0x31, 0x2c, 0x31, 0x3b, 0x31, 0x58, 0x31, 0x5a}; -const uint8_t HuffDecoderCommon::table11_16_emit_[7] = {0x32, 0x30, 0x32, 0x31, - 0x32, 0x32, 0x61}; -const uint16_t HuffDecoderCommon::table11_16_inner_[5] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0015}; -const uint8_t HuffDecoderCommon::table11_17_emit_[8] = {0x32, 0x63, 0x32, 0x65, - 0x32, 0x69, 0x32, 0x6f}; -const uint8_t HuffDecoderCommon::table11_18_emit_[12] = { +const uint8_t HuffDecoderCommon::table1_16_emit_[7] = {0x32, 0x30, 0x32, 0x31, + 0x32, 0x32, 0x61}; +const uint16_t HuffDecoderCommon::table1_16_inner_[4] = {0x000a, 0x008a, 0x010a, + 0x014a}; +const uint8_t HuffDecoderCommon::table1_17_emit_[8] = {0x32, 0x63, 0x32, 0x65, + 0x32, 0x69, 0x32, 0x6f}; +const uint8_t HuffDecoderCommon::table1_18_emit_[12] = { 0x32, 0x73, 0x32, 0x74, 0x32, 0x20, 0x32, 0x25, 0x32, 0x2d, 0x32, 0x2e}; -const uint8_t HuffDecoderCommon::table11_19_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_19_emit_[16] = { 0x32, 0x2f, 0x32, 0x33, 0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32, 0x38, 0x32, 0x39}; -const uint8_t HuffDecoderCommon::table11_20_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_20_emit_[16] = { 0x32, 0x3d, 0x32, 0x41, 0x32, 0x5f, 0x32, 0x62, 0x32, 0x64, 0x32, 0x66, 0x32, 0x67, 0x32, 0x68}; -const uint8_t HuffDecoderCommon::table11_21_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_21_emit_[20] = { 0x32, 0x6c, 0x32, 0x6d, 0x32, 0x6e, 0x32, 0x70, 0x32, 0x72, 0x32, 0x75, 0x32, 0x3a, 0x32, 0x42, 0x32, 0x43, 0x32, 0x44}; -const uint8_t HuffDecoderCommon::table11_22_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_22_emit_[32] = { 0x32, 0x45, 0x32, 0x46, 0x32, 0x47, 0x32, 0x48, 0x32, 0x49, 0x32, 0x4a, 0x32, 0x4b, 0x32, 0x4c, 0x32, 0x4d, 0x32, 0x4e, 0x32, 0x4f, 0x32, 0x50, 0x32, 0x51, 0x32, 0x52, 0x32, 0x53, 0x32, 0x54}; -const uint8_t HuffDecoderCommon::table11_23_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_23_emit_[36] = { 0x32, 0x55, 0x32, 0x56, 0x32, 0x57, 0x32, 0x59, 0x32, 0x6a, 0x32, 0x6b, 0x32, 0x71, 0x32, 0x76, 0x32, 0x77, 0x32, 0x78, 0x32, 0x79, 0x32, 0x7a, 0x32, 0x26, 0x32, 0x2a, 0x32, 0x2c, 0x32, 0x3b, 0x32, 0x58, 0x32, 0x5a}; -const uint8_t HuffDecoderCommon::table11_24_emit_[8] = {0x61, 0x30, 0x61, 0x31, - 0x61, 0x32, 0x61, 0x61}; -const uint8_t HuffDecoderCommon::table11_25_emit_[8] = {0x61, 0x63, 0x61, 0x65, - 0x61, 0x69, 0x61, 0x6f}; -const uint8_t HuffDecoderCommon::table11_26_emit_[12] = { +const uint8_t HuffDecoderCommon::table1_24_emit_[8] = {0x61, 0x30, 0x61, 0x31, + 0x61, 0x32, 0x61, 0x61}; +const uint8_t HuffDecoderCommon::table1_25_emit_[8] = {0x61, 0x63, 0x61, 0x65, + 0x61, 0x69, 0x61, 0x6f}; +const uint8_t HuffDecoderCommon::table1_26_emit_[12] = { 0x61, 0x73, 0x61, 0x74, 0x61, 0x20, 0x61, 0x25, 0x61, 0x2d, 0x61, 0x2e}; -const uint8_t HuffDecoderCommon::table11_27_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_27_emit_[16] = { 0x61, 0x2f, 0x61, 0x33, 0x61, 0x34, 0x61, 0x35, 0x61, 0x36, 0x61, 0x37, 0x61, 0x38, 0x61, 0x39}; -const uint8_t HuffDecoderCommon::table11_28_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_28_emit_[16] = { 0x61, 0x3d, 0x61, 0x41, 0x61, 0x5f, 0x61, 0x62, 0x61, 0x64, 0x61, 0x66, 0x61, 0x67, 0x61, 0x68}; -const uint8_t HuffDecoderCommon::table11_29_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_29_emit_[20] = { 0x61, 0x6c, 0x61, 0x6d, 0x61, 0x6e, 0x61, 0x70, 0x61, 0x72, 0x61, 0x75, 0x61, 0x3a, 0x61, 0x42, 0x61, 0x43, 0x61, 0x44}; -const uint8_t HuffDecoderCommon::table11_30_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_30_emit_[32] = { 0x61, 0x45, 0x61, 0x46, 0x61, 0x47, 0x61, 0x48, 0x61, 0x49, 0x61, 0x4a, 0x61, 0x4b, 0x61, 0x4c, 0x61, 0x4d, 0x61, 0x4e, 0x61, 0x4f, 0x61, 0x50, 0x61, 0x51, 0x61, 0x52, 0x61, 0x53, 0x61, 0x54}; -const uint8_t HuffDecoderCommon::table11_31_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_31_emit_[36] = { 0x61, 0x55, 0x61, 0x56, 0x61, 0x57, 0x61, 0x59, 0x61, 0x6a, 0x61, 0x6b, 0x61, 0x71, 0x61, 0x76, 0x61, 0x77, 0x61, 0x78, 0x61, 0x79, 0x61, 0x7a, 0x61, 0x26, 0x61, 0x2a, 0x61, 0x2c, 0x61, 0x3b, 0x61, 0x58, 0x61, 0x5a}; -const uint8_t HuffDecoderCommon::table11_32_emit_[8] = {0x63, 0x30, 0x63, 0x31, - 0x63, 0x32, 0x63, 0x61}; -const uint8_t HuffDecoderCommon::table11_33_emit_[7] = {0x63, 0x63, 0x65, 0x63, - 0x69, 0x63, 0x6f}; -const uint8_t HuffDecoderCommon::table11_34_emit_[12] = { +const uint8_t HuffDecoderCommon::table1_32_emit_[8] = {0x63, 0x30, 0x63, 0x31, + 0x63, 0x32, 0x63, 0x61}; +const uint8_t HuffDecoderCommon::table1_33_emit_[7] = {0x63, 0x63, 0x65, 0x63, + 0x69, 0x63, 0x6f}; +const uint8_t HuffDecoderCommon::table1_34_emit_[12] = { 0x63, 0x73, 0x63, 0x74, 0x63, 0x20, 0x63, 0x25, 0x63, 0x2d, 0x63, 0x2e}; -const uint8_t HuffDecoderCommon::table11_35_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_35_emit_[16] = { 0x63, 0x2f, 0x63, 0x33, 0x63, 0x34, 0x63, 0x35, 0x63, 0x36, 0x63, 0x37, 0x63, 0x38, 0x63, 0x39}; -const uint8_t HuffDecoderCommon::table11_36_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_36_emit_[16] = { 0x63, 0x3d, 0x63, 0x41, 0x63, 0x5f, 0x63, 0x62, 0x63, 0x64, 0x63, 0x66, 0x63, 0x67, 0x63, 0x68}; -const uint8_t HuffDecoderCommon::table11_37_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_37_emit_[20] = { 0x63, 0x6c, 0x63, 0x6d, 0x63, 0x6e, 0x63, 0x70, 0x63, 0x72, 0x63, 0x75, 0x63, 0x3a, 0x63, 0x42, 0x63, 0x43, 0x63, 0x44}; -const uint8_t HuffDecoderCommon::table11_38_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_38_emit_[32] = { 0x63, 0x45, 0x63, 0x46, 0x63, 0x47, 0x63, 0x48, 0x63, 0x49, 0x63, 0x4a, 0x63, 0x4b, 0x63, 0x4c, 0x63, 0x4d, 0x63, 0x4e, 0x63, 0x4f, 0x63, 0x50, 0x63, 0x51, 0x63, 0x52, 0x63, 0x53, 0x63, 0x54}; -const uint8_t HuffDecoderCommon::table11_39_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_39_emit_[36] = { 0x63, 0x55, 0x63, 0x56, 0x63, 0x57, 0x63, 0x59, 0x63, 0x6a, 0x63, 0x6b, 0x63, 0x71, 0x63, 0x76, 0x63, 0x77, 0x63, 0x78, 0x63, 0x79, 0x63, 0x7a, 0x63, 0x26, 0x63, 0x2a, 0x63, 0x2c, 0x63, 0x3b, 0x63, 0x58, 0x63, 0x5a}; -const uint8_t HuffDecoderCommon::table11_40_emit_[8] = {0x65, 0x30, 0x65, 0x31, - 0x65, 0x32, 0x65, 0x61}; -const uint8_t HuffDecoderCommon::table11_41_emit_[7] = {0x65, 0x63, 0x65, 0x65, - 0x69, 0x65, 0x6f}; -const uint8_t HuffDecoderCommon::table11_42_emit_[12] = { +const uint8_t HuffDecoderCommon::table1_40_emit_[8] = {0x65, 0x30, 0x65, 0x31, + 0x65, 0x32, 0x65, 0x61}; +const uint8_t HuffDecoderCommon::table1_41_emit_[7] = {0x65, 0x63, 0x65, 0x65, + 0x69, 0x65, 0x6f}; +const uint8_t HuffDecoderCommon::table1_42_emit_[12] = { 0x65, 0x73, 0x65, 0x74, 0x65, 0x20, 0x65, 0x25, 0x65, 0x2d, 0x65, 0x2e}; -const uint8_t HuffDecoderCommon::table11_43_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_43_emit_[16] = { 0x65, 0x2f, 0x65, 0x33, 0x65, 0x34, 0x65, 0x35, 0x65, 0x36, 0x65, 0x37, 0x65, 0x38, 0x65, 0x39}; -const uint8_t HuffDecoderCommon::table11_44_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_44_emit_[16] = { 0x65, 0x3d, 0x65, 0x41, 0x65, 0x5f, 0x65, 0x62, 0x65, 0x64, 0x65, 0x66, 0x65, 0x67, 0x65, 0x68}; -const uint8_t HuffDecoderCommon::table11_45_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_45_emit_[20] = { 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x65, 0x70, 0x65, 0x72, 0x65, 0x75, 0x65, 0x3a, 0x65, 0x42, 0x65, 0x43, 0x65, 0x44}; -const uint8_t HuffDecoderCommon::table11_46_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_46_emit_[32] = { 0x65, 0x45, 0x65, 0x46, 0x65, 0x47, 0x65, 0x48, 0x65, 0x49, 0x65, 0x4a, 0x65, 0x4b, 0x65, 0x4c, 0x65, 0x4d, 0x65, 0x4e, 0x65, 0x4f, 0x65, 0x50, 0x65, 0x51, 0x65, 0x52, 0x65, 0x53, 0x65, 0x54}; -const uint8_t HuffDecoderCommon::table11_47_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_47_emit_[36] = { 0x65, 0x55, 0x65, 0x56, 0x65, 0x57, 0x65, 0x59, 0x65, 0x6a, 0x65, 0x6b, 0x65, 0x71, 0x65, 0x76, 0x65, 0x77, 0x65, 0x78, 0x65, 0x79, 0x65, 0x7a, 0x65, 0x26, 0x65, 0x2a, 0x65, 0x2c, 0x65, 0x3b, 0x65, 0x58, 0x65, 0x5a}; -const uint8_t HuffDecoderCommon::table11_48_emit_[8] = {0x69, 0x30, 0x69, 0x31, - 0x69, 0x32, 0x69, 0x61}; -const uint8_t HuffDecoderCommon::table11_49_emit_[7] = {0x69, 0x63, 0x69, 0x65, - 0x69, 0x69, 0x6f}; -const uint8_t HuffDecoderCommon::table11_50_emit_[12] = { +const uint8_t HuffDecoderCommon::table1_48_emit_[8] = {0x69, 0x30, 0x69, 0x31, + 0x69, 0x32, 0x69, 0x61}; +const uint8_t HuffDecoderCommon::table1_49_emit_[7] = {0x69, 0x63, 0x69, 0x65, + 0x69, 0x69, 0x6f}; +const uint8_t HuffDecoderCommon::table1_50_emit_[12] = { 0x69, 0x73, 0x69, 0x74, 0x69, 0x20, 0x69, 0x25, 0x69, 0x2d, 0x69, 0x2e}; -const uint8_t HuffDecoderCommon::table11_51_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_51_emit_[16] = { 0x69, 0x2f, 0x69, 0x33, 0x69, 0x34, 0x69, 0x35, 0x69, 0x36, 0x69, 0x37, 0x69, 0x38, 0x69, 0x39}; -const uint8_t HuffDecoderCommon::table11_52_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_52_emit_[16] = { 0x69, 0x3d, 0x69, 0x41, 0x69, 0x5f, 0x69, 0x62, 0x69, 0x64, 0x69, 0x66, 0x69, 0x67, 0x69, 0x68}; -const uint8_t HuffDecoderCommon::table11_53_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_53_emit_[20] = { 0x69, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x69, 0x70, 0x69, 0x72, 0x69, 0x75, 0x69, 0x3a, 0x69, 0x42, 0x69, 0x43, 0x69, 0x44}; -const uint8_t HuffDecoderCommon::table11_54_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_54_emit_[32] = { 0x69, 0x45, 0x69, 0x46, 0x69, 0x47, 0x69, 0x48, 0x69, 0x49, 0x69, 0x4a, 0x69, 0x4b, 0x69, 0x4c, 0x69, 0x4d, 0x69, 0x4e, 0x69, 0x4f, 0x69, 0x50, 0x69, 0x51, 0x69, 0x52, 0x69, 0x53, 0x69, 0x54}; -const uint8_t HuffDecoderCommon::table11_55_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_55_emit_[36] = { 0x69, 0x55, 0x69, 0x56, 0x69, 0x57, 0x69, 0x59, 0x69, 0x6a, 0x69, 0x6b, 0x69, 0x71, 0x69, 0x76, 0x69, 0x77, 0x69, 0x78, 0x69, 0x79, 0x69, 0x7a, 0x69, 0x26, 0x69, 0x2a, 0x69, 0x2c, 0x69, 0x3b, 0x69, 0x58, 0x69, 0x5a}; -const uint8_t HuffDecoderCommon::table11_56_emit_[8] = {0x6f, 0x30, 0x6f, 0x31, - 0x6f, 0x32, 0x6f, 0x61}; -const uint8_t HuffDecoderCommon::table11_57_emit_[8] = {0x6f, 0x63, 0x6f, 0x65, - 0x6f, 0x69, 0x6f, 0x6f}; -const uint8_t HuffDecoderCommon::table11_58_emit_[12] = { +const uint8_t HuffDecoderCommon::table1_56_emit_[8] = {0x6f, 0x30, 0x6f, 0x31, + 0x6f, 0x32, 0x6f, 0x61}; +const uint8_t HuffDecoderCommon::table1_57_emit_[8] = {0x6f, 0x63, 0x6f, 0x65, + 0x6f, 0x69, 0x6f, 0x6f}; +const uint8_t HuffDecoderCommon::table1_58_emit_[12] = { 0x6f, 0x73, 0x6f, 0x74, 0x6f, 0x20, 0x6f, 0x25, 0x6f, 0x2d, 0x6f, 0x2e}; -const uint8_t HuffDecoderCommon::table11_59_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_59_emit_[16] = { 0x6f, 0x2f, 0x6f, 0x33, 0x6f, 0x34, 0x6f, 0x35, 0x6f, 0x36, 0x6f, 0x37, 0x6f, 0x38, 0x6f, 0x39}; -const uint8_t HuffDecoderCommon::table11_60_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_60_emit_[16] = { 0x6f, 0x3d, 0x6f, 0x41, 0x6f, 0x5f, 0x6f, 0x62, 0x6f, 0x64, 0x6f, 0x66, 0x6f, 0x67, 0x6f, 0x68}; -const uint8_t HuffDecoderCommon::table11_61_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_61_emit_[20] = { 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x6f, 0x70, 0x6f, 0x72, 0x6f, 0x75, 0x6f, 0x3a, 0x6f, 0x42, 0x6f, 0x43, 0x6f, 0x44}; -const uint8_t HuffDecoderCommon::table11_62_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_62_emit_[32] = { 0x6f, 0x45, 0x6f, 0x46, 0x6f, 0x47, 0x6f, 0x48, 0x6f, 0x49, 0x6f, 0x4a, 0x6f, 0x4b, 0x6f, 0x4c, 0x6f, 0x4d, 0x6f, 0x4e, 0x6f, 0x4f, 0x6f, 0x50, 0x6f, 0x51, 0x6f, 0x52, 0x6f, 0x53, 0x6f, 0x54}; -const uint8_t HuffDecoderCommon::table11_63_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_63_emit_[36] = { 0x6f, 0x55, 0x6f, 0x56, 0x6f, 0x57, 0x6f, 0x59, 0x6f, 0x6a, 0x6f, 0x6b, 0x6f, 0x71, 0x6f, 0x76, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, 0x26, 0x6f, 0x2a, 0x6f, 0x2c, 0x6f, 0x3b, 0x6f, 0x58, 0x6f, 0x5a}; -const uint8_t HuffDecoderCommon::table11_64_emit_[8] = {0x73, 0x30, 0x73, 0x31, - 0x73, 0x32, 0x73, 0x61}; -const uint8_t HuffDecoderCommon::table11_65_emit_[8] = {0x73, 0x63, 0x73, 0x65, - 0x73, 0x69, 0x73, 0x6f}; -const uint8_t HuffDecoderCommon::table11_66_emit_[11] = { +const uint8_t HuffDecoderCommon::table1_64_emit_[8] = {0x73, 0x30, 0x73, 0x31, + 0x73, 0x32, 0x73, 0x61}; +const uint8_t HuffDecoderCommon::table1_65_emit_[8] = {0x73, 0x63, 0x73, 0x65, + 0x73, 0x69, 0x73, 0x6f}; +const uint8_t HuffDecoderCommon::table1_66_emit_[11] = { 0x73, 0x73, 0x74, 0x73, 0x20, 0x73, 0x25, 0x73, 0x2d, 0x73, 0x2e}; -const uint16_t HuffDecoderCommon::table11_66_inner_[7] = { - 0x0000, 0x0001, 0x0005, 0x000d, 0x0015, 0x001d, 0x0025}; -const uint8_t HuffDecoderCommon::table11_67_emit_[16] = { +const uint16_t HuffDecoderCommon::table1_66_inner_[6] = { + 0x000a, 0x004a, 0x00cb, 0x014b, 0x01cb, 0x024b}; +const uint8_t HuffDecoderCommon::table1_67_emit_[16] = { 0x73, 0x2f, 0x73, 0x33, 0x73, 0x34, 0x73, 0x35, 0x73, 0x36, 0x73, 0x37, 0x73, 0x38, 0x73, 0x39}; -const uint8_t HuffDecoderCommon::table11_68_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_68_emit_[16] = { 0x73, 0x3d, 0x73, 0x41, 0x73, 0x5f, 0x73, 0x62, 0x73, 0x64, 0x73, 0x66, 0x73, 0x67, 0x73, 0x68}; -const uint8_t HuffDecoderCommon::table11_69_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_69_emit_[20] = { 0x73, 0x6c, 0x73, 0x6d, 0x73, 0x6e, 0x73, 0x70, 0x73, 0x72, 0x73, 0x75, 0x73, 0x3a, 0x73, 0x42, 0x73, 0x43, 0x73, 0x44}; -const uint8_t HuffDecoderCommon::table11_70_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_70_emit_[32] = { 0x73, 0x45, 0x73, 0x46, 0x73, 0x47, 0x73, 0x48, 0x73, 0x49, 0x73, 0x4a, 0x73, 0x4b, 0x73, 0x4c, 0x73, 0x4d, 0x73, 0x4e, 0x73, 0x4f, 0x73, 0x50, 0x73, 0x51, 0x73, 0x52, 0x73, 0x53, 0x73, 0x54}; -const uint8_t HuffDecoderCommon::table11_71_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_71_emit_[36] = { 0x73, 0x55, 0x73, 0x56, 0x73, 0x57, 0x73, 0x59, 0x73, 0x6a, 0x73, 0x6b, 0x73, 0x71, 0x73, 0x76, 0x73, 0x77, 0x73, 0x78, 0x73, 0x79, 0x73, 0x7a, 0x73, 0x26, 0x73, 0x2a, 0x73, 0x2c, 0x73, 0x3b, 0x73, 0x58, 0x73, 0x5a}; -const uint8_t HuffDecoderCommon::table11_72_emit_[8] = {0x74, 0x30, 0x74, 0x31, - 0x74, 0x32, 0x74, 0x61}; -const uint8_t HuffDecoderCommon::table11_73_emit_[8] = {0x74, 0x63, 0x74, 0x65, - 0x74, 0x69, 0x74, 0x6f}; -const uint8_t HuffDecoderCommon::table11_74_emit_[11] = { +const uint8_t HuffDecoderCommon::table1_72_emit_[8] = {0x74, 0x30, 0x74, 0x31, + 0x74, 0x32, 0x74, 0x61}; +const uint8_t HuffDecoderCommon::table1_73_emit_[8] = {0x74, 0x63, 0x74, 0x65, + 0x74, 0x69, 0x74, 0x6f}; +const uint8_t HuffDecoderCommon::table1_74_emit_[11] = { 0x74, 0x73, 0x74, 0x74, 0x20, 0x74, 0x25, 0x74, 0x2d, 0x74, 0x2e}; -const uint16_t HuffDecoderCommon::table11_74_inner_[7] = { - 0x0000, 0x0001, 0x0009, 0x000d, 0x0015, 0x001d, 0x0025}; -const uint8_t HuffDecoderCommon::table11_75_emit_[16] = { +const uint16_t HuffDecoderCommon::table1_74_inner_[6] = { + 0x000a, 0x008a, 0x00cb, 0x014b, 0x01cb, 0x024b}; +const uint8_t HuffDecoderCommon::table1_75_emit_[16] = { 0x74, 0x2f, 0x74, 0x33, 0x74, 0x34, 0x74, 0x35, 0x74, 0x36, 0x74, 0x37, 0x74, 0x38, 0x74, 0x39}; -const uint8_t HuffDecoderCommon::table11_76_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_76_emit_[16] = { 0x74, 0x3d, 0x74, 0x41, 0x74, 0x5f, 0x74, 0x62, 0x74, 0x64, 0x74, 0x66, 0x74, 0x67, 0x74, 0x68}; -const uint8_t HuffDecoderCommon::table11_77_emit_[20] = { +const uint8_t HuffDecoderCommon::table1_77_emit_[20] = { 0x74, 0x6c, 0x74, 0x6d, 0x74, 0x6e, 0x74, 0x70, 0x74, 0x72, 0x74, 0x75, 0x74, 0x3a, 0x74, 0x42, 0x74, 0x43, 0x74, 0x44}; -const uint8_t HuffDecoderCommon::table11_78_emit_[32] = { +const uint8_t HuffDecoderCommon::table1_78_emit_[32] = { 0x74, 0x45, 0x74, 0x46, 0x74, 0x47, 0x74, 0x48, 0x74, 0x49, 0x74, 0x4a, 0x74, 0x4b, 0x74, 0x4c, 0x74, 0x4d, 0x74, 0x4e, 0x74, 0x4f, 0x74, 0x50, 0x74, 0x51, 0x74, 0x52, 0x74, 0x53, 0x74, 0x54}; -const uint8_t HuffDecoderCommon::table11_79_emit_[36] = { +const uint8_t HuffDecoderCommon::table1_79_emit_[36] = { 0x74, 0x55, 0x74, 0x56, 0x74, 0x57, 0x74, 0x59, 0x74, 0x6a, 0x74, 0x6b, 0x74, 0x71, 0x74, 0x76, 0x74, 0x77, 0x74, 0x78, 0x74, 0x79, 0x74, 0x7a, 0x74, 0x26, 0x74, 0x2a, 0x74, 0x2c, 0x74, 0x3b, 0x74, 0x58, 0x74, 0x5a}; -const uint8_t HuffDecoderCommon::table11_80_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_80_emit_[16] = { 0x20, 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x61, 0x20, 0x63, 0x20, 0x65, 0x20, 0x69, 0x20, 0x6f}; -const uint8_t HuffDecoderCommon::table11_81_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_81_emit_[27] = { 0x20, 0x73, 0x20, 0x74, 0x20, 0x20, 0x25, 0x20, 0x2d, 0x20, 0x2e, 0x20, 0x2f, 0x20, 0x33, 0x20, 0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, 0x38, 0x20, 0x39}; -const uint16_t HuffDecoderCommon::table11_81_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0015, 0x001d, 0x0025, 0x002d, - 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_82_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_81_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x014c, 0x01cc, 0x024c, 0x02cc, + 0x034c, 0x03cc, 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_81_outer_[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, + 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13}; +const uint8_t HuffDecoderCommon::table1_82_emit_[36] = { 0x20, 0x3d, 0x20, 0x41, 0x20, 0x5f, 0x20, 0x62, 0x20, 0x64, 0x20, 0x66, 0x20, 0x67, 0x20, 0x68, 0x20, 0x6c, 0x20, 0x6d, 0x20, 0x6e, 0x20, 0x70, 0x20, 0x72, 0x20, 0x75, 0x20, 0x3a, 0x20, 0x42, 0x20, 0x43, 0x20, 0x44}; -const uint8_t HuffDecoderCommon::table11_83_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_82_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x040c, + 0x048c, 0x050c, 0x058c, 0x060c, 0x068c, 0x070d, 0x078d, 0x080d, 0x088d}; +const uint8_t HuffDecoderCommon::table1_82_outer_[64] = { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17}; +const uint8_t HuffDecoderCommon::table1_83_emit_[68] = { 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, 0x48, 0x20, 0x49, 0x20, 0x4a, 0x20, 0x4b, 0x20, 0x4c, 0x20, 0x4d, 0x20, 0x4e, 0x20, 0x4f, 0x20, 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, 0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, 0x59, 0x20, 0x6a, 0x20, 0x6b, 0x20, 0x71, 0x20, 0x76, 0x20, 0x77, 0x20, 0x78, 0x20, 0x79, 0x20, 0x7a, 0x20, 0x26, 0x20, 0x2a, 0x20, 0x2c, 0x20, 0x3b, 0x20, 0x58, 0x20, 0x5a}; -const uint8_t HuffDecoderCommon::table11_84_emit_[16] = { +const uint16_t HuffDecoderCommon::table1_83_inner_[35] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, 0x040d, + 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070d, 0x078d, 0x080d, 0x088d, + 0x090d, 0x098d, 0x0a0d, 0x0a8d, 0x0b0d, 0x0b8d, 0x0c0d, 0x0c8d, 0x0d0d, + 0x0d8d, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, 0x100e, 0x108e, 0x0016}; +const uint8_t HuffDecoderCommon::table1_83_outer_[64] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, + 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, + 24, 24, 25, 25, 26, 26, 27, 27, 28, 29, 30, 31, 32, 33, 34, 34}; +const uint8_t HuffDecoderCommon::table1_84_emit_[16] = { 0x25, 0x30, 0x25, 0x31, 0x25, 0x32, 0x25, 0x61, 0x25, 0x63, 0x25, 0x65, 0x25, 0x69, 0x25, 0x6f}; -const uint8_t HuffDecoderCommon::table11_85_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_85_emit_[27] = { 0x25, 0x73, 0x25, 0x74, 0x25, 0x20, 0x25, 0x25, 0x2d, 0x25, 0x2e, 0x25, 0x2f, 0x25, 0x33, 0x25, 0x34, 0x25, 0x35, 0x25, 0x36, 0x25, 0x37, 0x25, 0x38, 0x25, 0x39}; -const uint16_t HuffDecoderCommon::table11_85_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x001d, 0x0025, 0x002d, - 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_86_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_85_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x01cc, 0x024c, 0x02cc, + 0x034c, 0x03cc, 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_86_emit_[36] = { 0x25, 0x3d, 0x25, 0x41, 0x25, 0x5f, 0x25, 0x62, 0x25, 0x64, 0x25, 0x66, 0x25, 0x67, 0x25, 0x68, 0x25, 0x6c, 0x25, 0x6d, 0x25, 0x6e, 0x25, 0x70, 0x25, 0x72, 0x25, 0x75, 0x25, 0x3a, 0x25, 0x42, 0x25, 0x43, 0x25, 0x44}; -const uint8_t HuffDecoderCommon::table11_87_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_87_emit_[68] = { 0x25, 0x45, 0x25, 0x46, 0x25, 0x47, 0x25, 0x48, 0x25, 0x49, 0x25, 0x4a, 0x25, 0x4b, 0x25, 0x4c, 0x25, 0x4d, 0x25, 0x4e, 0x25, 0x4f, 0x25, 0x50, 0x25, 0x51, 0x25, 0x52, 0x25, 0x53, 0x25, 0x54, 0x25, 0x55, 0x25, 0x56, 0x25, 0x57, 0x25, 0x59, 0x25, 0x6a, 0x25, 0x6b, 0x25, 0x71, 0x25, 0x76, 0x25, 0x77, 0x25, 0x78, 0x25, 0x79, 0x25, 0x7a, 0x25, 0x26, 0x25, 0x2a, 0x25, 0x2c, 0x25, 0x3b, 0x25, 0x58, 0x25, 0x5a}; -const uint8_t HuffDecoderCommon::table11_88_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_88_emit_[16] = { 0x2d, 0x30, 0x2d, 0x31, 0x2d, 0x32, 0x2d, 0x61, 0x2d, 0x63, 0x2d, 0x65, 0x2d, 0x69, 0x2d, 0x6f}; -const uint8_t HuffDecoderCommon::table11_89_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_89_emit_[27] = { 0x2d, 0x73, 0x2d, 0x74, 0x2d, 0x20, 0x2d, 0x25, 0x2d, 0x2d, 0x2e, 0x2d, 0x2f, 0x2d, 0x33, 0x2d, 0x34, 0x2d, 0x35, 0x2d, 0x36, 0x2d, 0x37, 0x2d, 0x38, 0x2d, 0x39}; -const uint16_t HuffDecoderCommon::table11_89_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0025, 0x002d, - 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_90_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_89_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x024c, 0x02cc, + 0x034c, 0x03cc, 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_90_emit_[36] = { 0x2d, 0x3d, 0x2d, 0x41, 0x2d, 0x5f, 0x2d, 0x62, 0x2d, 0x64, 0x2d, 0x66, 0x2d, 0x67, 0x2d, 0x68, 0x2d, 0x6c, 0x2d, 0x6d, 0x2d, 0x6e, 0x2d, 0x70, 0x2d, 0x72, 0x2d, 0x75, 0x2d, 0x3a, 0x2d, 0x42, 0x2d, 0x43, 0x2d, 0x44}; -const uint8_t HuffDecoderCommon::table11_91_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_91_emit_[68] = { 0x2d, 0x45, 0x2d, 0x46, 0x2d, 0x47, 0x2d, 0x48, 0x2d, 0x49, 0x2d, 0x4a, 0x2d, 0x4b, 0x2d, 0x4c, 0x2d, 0x4d, 0x2d, 0x4e, 0x2d, 0x4f, 0x2d, 0x50, 0x2d, 0x51, 0x2d, 0x52, 0x2d, 0x53, 0x2d, 0x54, 0x2d, 0x55, 0x2d, 0x56, 0x2d, 0x57, 0x2d, 0x59, 0x2d, 0x6a, 0x2d, 0x6b, 0x2d, 0x71, 0x2d, 0x76, 0x2d, 0x77, 0x2d, 0x78, 0x2d, 0x79, 0x2d, 0x7a, 0x2d, 0x26, 0x2d, 0x2a, 0x2d, 0x2c, 0x2d, 0x3b, 0x2d, 0x58, 0x2d, 0x5a}; -const uint8_t HuffDecoderCommon::table11_92_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_92_emit_[16] = { 0x2e, 0x30, 0x2e, 0x31, 0x2e, 0x32, 0x2e, 0x61, 0x2e, 0x63, 0x2e, 0x65, 0x2e, 0x69, 0x2e, 0x6f}; -const uint8_t HuffDecoderCommon::table11_93_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_93_emit_[27] = { 0x2e, 0x73, 0x2e, 0x74, 0x2e, 0x20, 0x2e, 0x25, 0x2e, 0x2d, 0x2e, 0x2e, 0x2f, 0x2e, 0x33, 0x2e, 0x34, 0x2e, 0x35, 0x2e, 0x36, 0x2e, 0x37, 0x2e, 0x38, 0x2e, 0x39}; -const uint16_t HuffDecoderCommon::table11_93_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x002d, - 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_94_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_93_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x02cc, + 0x034c, 0x03cc, 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_94_emit_[36] = { 0x2e, 0x3d, 0x2e, 0x41, 0x2e, 0x5f, 0x2e, 0x62, 0x2e, 0x64, 0x2e, 0x66, 0x2e, 0x67, 0x2e, 0x68, 0x2e, 0x6c, 0x2e, 0x6d, 0x2e, 0x6e, 0x2e, 0x70, 0x2e, 0x72, 0x2e, 0x75, 0x2e, 0x3a, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x44}; -const uint8_t HuffDecoderCommon::table11_95_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_95_emit_[68] = { 0x2e, 0x45, 0x2e, 0x46, 0x2e, 0x47, 0x2e, 0x48, 0x2e, 0x49, 0x2e, 0x4a, 0x2e, 0x4b, 0x2e, 0x4c, 0x2e, 0x4d, 0x2e, 0x4e, 0x2e, 0x4f, 0x2e, 0x50, 0x2e, 0x51, 0x2e, 0x52, 0x2e, 0x53, 0x2e, 0x54, 0x2e, 0x55, 0x2e, 0x56, 0x2e, 0x57, 0x2e, 0x59, 0x2e, 0x6a, 0x2e, 0x6b, 0x2e, 0x71, 0x2e, 0x76, 0x2e, 0x77, 0x2e, 0x78, 0x2e, 0x79, 0x2e, 0x7a, 0x2e, 0x26, 0x2e, 0x2a, 0x2e, 0x2c, 0x2e, 0x3b, 0x2e, 0x58, 0x2e, 0x5a}; -const uint8_t HuffDecoderCommon::table11_96_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_96_emit_[16] = { 0x2f, 0x30, 0x2f, 0x31, 0x2f, 0x32, 0x2f, 0x61, 0x2f, 0x63, 0x2f, 0x65, 0x2f, 0x69, 0x2f, 0x6f}; -const uint8_t HuffDecoderCommon::table11_97_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_97_emit_[27] = { 0x2f, 0x73, 0x2f, 0x74, 0x2f, 0x20, 0x2f, 0x25, 0x2f, 0x2d, 0x2f, 0x2e, 0x2f, 0x2f, 0x33, 0x2f, 0x34, 0x2f, 0x35, 0x2f, 0x36, 0x2f, 0x37, 0x2f, 0x38, 0x2f, 0x39}; -const uint16_t HuffDecoderCommon::table11_97_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_98_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_97_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x034c, 0x03cc, 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_98_emit_[36] = { 0x2f, 0x3d, 0x2f, 0x41, 0x2f, 0x5f, 0x2f, 0x62, 0x2f, 0x64, 0x2f, 0x66, 0x2f, 0x67, 0x2f, 0x68, 0x2f, 0x6c, 0x2f, 0x6d, 0x2f, 0x6e, 0x2f, 0x70, 0x2f, 0x72, 0x2f, 0x75, 0x2f, 0x3a, 0x2f, 0x42, 0x2f, 0x43, 0x2f, 0x44}; -const uint8_t HuffDecoderCommon::table11_99_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_99_emit_[68] = { 0x2f, 0x45, 0x2f, 0x46, 0x2f, 0x47, 0x2f, 0x48, 0x2f, 0x49, 0x2f, 0x4a, 0x2f, 0x4b, 0x2f, 0x4c, 0x2f, 0x4d, 0x2f, 0x4e, 0x2f, 0x4f, 0x2f, 0x50, 0x2f, 0x51, 0x2f, 0x52, 0x2f, 0x53, 0x2f, 0x54, 0x2f, 0x55, 0x2f, 0x56, 0x2f, 0x57, 0x2f, 0x59, 0x2f, 0x6a, 0x2f, 0x6b, 0x2f, 0x71, 0x2f, 0x76, 0x2f, 0x77, 0x2f, 0x78, 0x2f, 0x79, 0x2f, 0x7a, 0x2f, 0x26, 0x2f, 0x2a, 0x2f, 0x2c, 0x2f, 0x3b, 0x2f, 0x58, 0x2f, 0x5a}; -const uint8_t HuffDecoderCommon::table11_100_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_100_emit_[16] = { 0x33, 0x30, 0x33, 0x31, 0x33, 0x32, 0x33, 0x61, 0x33, 0x63, 0x33, 0x65, 0x33, 0x69, 0x33, 0x6f}; -const uint8_t HuffDecoderCommon::table11_101_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_101_emit_[27] = { 0x33, 0x73, 0x33, 0x74, 0x33, 0x20, 0x33, 0x25, 0x33, 0x2d, 0x33, 0x2e, 0x33, 0x2f, 0x33, 0x33, 0x34, 0x33, 0x35, 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39}; -const uint16_t HuffDecoderCommon::table11_101_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_102_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_101_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x03cc, 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_102_emit_[36] = { 0x33, 0x3d, 0x33, 0x41, 0x33, 0x5f, 0x33, 0x62, 0x33, 0x64, 0x33, 0x66, 0x33, 0x67, 0x33, 0x68, 0x33, 0x6c, 0x33, 0x6d, 0x33, 0x6e, 0x33, 0x70, 0x33, 0x72, 0x33, 0x75, 0x33, 0x3a, 0x33, 0x42, 0x33, 0x43, 0x33, 0x44}; -const uint8_t HuffDecoderCommon::table11_103_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_103_emit_[68] = { 0x33, 0x45, 0x33, 0x46, 0x33, 0x47, 0x33, 0x48, 0x33, 0x49, 0x33, 0x4a, 0x33, 0x4b, 0x33, 0x4c, 0x33, 0x4d, 0x33, 0x4e, 0x33, 0x4f, 0x33, 0x50, 0x33, 0x51, 0x33, 0x52, 0x33, 0x53, 0x33, 0x54, 0x33, 0x55, 0x33, 0x56, 0x33, 0x57, 0x33, 0x59, 0x33, 0x6a, 0x33, 0x6b, 0x33, 0x71, 0x33, 0x76, 0x33, 0x77, 0x33, 0x78, 0x33, 0x79, 0x33, 0x7a, 0x33, 0x26, 0x33, 0x2a, 0x33, 0x2c, 0x33, 0x3b, 0x33, 0x58, 0x33, 0x5a}; -const uint8_t HuffDecoderCommon::table11_104_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_104_emit_[16] = { 0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x61, 0x34, 0x63, 0x34, 0x65, 0x34, 0x69, 0x34, 0x6f}; -const uint8_t HuffDecoderCommon::table11_105_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_105_emit_[27] = { 0x34, 0x73, 0x34, 0x74, 0x34, 0x20, 0x34, 0x25, 0x34, 0x2d, 0x34, 0x2e, 0x34, 0x2f, 0x34, 0x33, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, 0x34, 0x38, 0x34, 0x39}; -const uint16_t HuffDecoderCommon::table11_105_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_106_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_105_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x040c, 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_106_emit_[36] = { 0x34, 0x3d, 0x34, 0x41, 0x34, 0x5f, 0x34, 0x62, 0x34, 0x64, 0x34, 0x66, 0x34, 0x67, 0x34, 0x68, 0x34, 0x6c, 0x34, 0x6d, 0x34, 0x6e, 0x34, 0x70, 0x34, 0x72, 0x34, 0x75, 0x34, 0x3a, 0x34, 0x42, 0x34, 0x43, 0x34, 0x44}; -const uint8_t HuffDecoderCommon::table11_107_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_107_emit_[68] = { 0x34, 0x45, 0x34, 0x46, 0x34, 0x47, 0x34, 0x48, 0x34, 0x49, 0x34, 0x4a, 0x34, 0x4b, 0x34, 0x4c, 0x34, 0x4d, 0x34, 0x4e, 0x34, 0x4f, 0x34, 0x50, 0x34, 0x51, 0x34, 0x52, 0x34, 0x53, 0x34, 0x54, 0x34, 0x55, 0x34, 0x56, 0x34, 0x57, 0x34, 0x59, 0x34, 0x6a, 0x34, 0x6b, 0x34, 0x71, 0x34, 0x76, 0x34, 0x77, 0x34, 0x78, 0x34, 0x79, 0x34, 0x7a, 0x34, 0x26, 0x34, 0x2a, 0x34, 0x2c, 0x34, 0x3b, 0x34, 0x58, 0x34, 0x5a}; -const uint8_t HuffDecoderCommon::table11_108_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_108_emit_[16] = { 0x35, 0x30, 0x35, 0x31, 0x35, 0x32, 0x35, 0x61, 0x35, 0x63, 0x35, 0x65, 0x35, 0x69, 0x35, 0x6f}; -const uint8_t HuffDecoderCommon::table11_109_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_109_emit_[27] = { 0x35, 0x73, 0x35, 0x74, 0x35, 0x20, 0x35, 0x25, 0x35, 0x2d, 0x35, 0x2e, 0x35, 0x2f, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39}; -const uint16_t HuffDecoderCommon::table11_109_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x004d, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_110_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_109_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x040c, 0x048c, 0x04cc, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_110_emit_[36] = { 0x35, 0x3d, 0x35, 0x41, 0x35, 0x5f, 0x35, 0x62, 0x35, 0x64, 0x35, 0x66, 0x35, 0x67, 0x35, 0x68, 0x35, 0x6c, 0x35, 0x6d, 0x35, 0x6e, 0x35, 0x70, 0x35, 0x72, 0x35, 0x75, 0x35, 0x3a, 0x35, 0x42, 0x35, 0x43, 0x35, 0x44}; -const uint8_t HuffDecoderCommon::table11_111_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_111_emit_[68] = { 0x35, 0x45, 0x35, 0x46, 0x35, 0x47, 0x35, 0x48, 0x35, 0x49, 0x35, 0x4a, 0x35, 0x4b, 0x35, 0x4c, 0x35, 0x4d, 0x35, 0x4e, 0x35, 0x4f, 0x35, 0x50, 0x35, 0x51, 0x35, 0x52, 0x35, 0x53, 0x35, 0x54, 0x35, 0x55, 0x35, 0x56, 0x35, 0x57, 0x35, 0x59, 0x35, 0x6a, 0x35, 0x6b, 0x35, 0x71, 0x35, 0x76, 0x35, 0x77, 0x35, 0x78, 0x35, 0x79, 0x35, 0x7a, 0x35, 0x26, 0x35, 0x2a, 0x35, 0x2c, 0x35, 0x3b, 0x35, 0x58, 0x35, 0x5a}; -const uint8_t HuffDecoderCommon::table11_112_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_112_emit_[16] = { 0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x61, 0x36, 0x63, 0x36, 0x65, 0x36, 0x69, 0x36, 0x6f}; -const uint8_t HuffDecoderCommon::table11_113_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_113_emit_[27] = { 0x36, 0x73, 0x36, 0x74, 0x36, 0x20, 0x36, 0x25, 0x36, 0x2d, 0x36, 0x2e, 0x36, 0x2f, 0x36, 0x33, 0x36, 0x34, 0x36, 0x35, 0x36, 0x36, 0x37, 0x36, 0x38, 0x36, 0x39}; -const uint16_t HuffDecoderCommon::table11_113_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0055, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_114_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_113_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x040c, 0x048c, 0x050c, 0x054c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_114_emit_[36] = { 0x36, 0x3d, 0x36, 0x41, 0x36, 0x5f, 0x36, 0x62, 0x36, 0x64, 0x36, 0x66, 0x36, 0x67, 0x36, 0x68, 0x36, 0x6c, 0x36, 0x6d, 0x36, 0x6e, 0x36, 0x70, 0x36, 0x72, 0x36, 0x75, 0x36, 0x3a, 0x36, 0x42, 0x36, 0x43, 0x36, 0x44}; -const uint8_t HuffDecoderCommon::table11_115_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_115_emit_[68] = { 0x36, 0x45, 0x36, 0x46, 0x36, 0x47, 0x36, 0x48, 0x36, 0x49, 0x36, 0x4a, 0x36, 0x4b, 0x36, 0x4c, 0x36, 0x4d, 0x36, 0x4e, 0x36, 0x4f, 0x36, 0x50, 0x36, 0x51, 0x36, 0x52, 0x36, 0x53, 0x36, 0x54, 0x36, 0x55, 0x36, 0x56, 0x36, 0x57, 0x36, 0x59, 0x36, 0x6a, 0x36, 0x6b, 0x36, 0x71, 0x36, 0x76, 0x36, 0x77, 0x36, 0x78, 0x36, 0x79, 0x36, 0x7a, 0x36, 0x26, 0x36, 0x2a, 0x36, 0x2c, 0x36, 0x3b, 0x36, 0x58, 0x36, 0x5a}; -const uint8_t HuffDecoderCommon::table11_116_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_116_emit_[16] = { 0x37, 0x30, 0x37, 0x31, 0x37, 0x32, 0x37, 0x61, 0x37, 0x63, 0x37, 0x65, 0x37, 0x69, 0x37, 0x6f}; -const uint8_t HuffDecoderCommon::table11_117_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_117_emit_[27] = { 0x37, 0x73, 0x37, 0x74, 0x37, 0x20, 0x37, 0x25, 0x37, 0x2d, 0x37, 0x2e, 0x37, 0x2f, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 0x37, 0x36, 0x37, 0x37, 0x38, 0x37, 0x39}; -const uint16_t HuffDecoderCommon::table11_117_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x005d, 0x0065}; -const uint8_t HuffDecoderCommon::table11_118_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_117_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x040c, 0x048c, 0x050c, 0x058c, 0x05cc, 0x064c}; +const uint8_t HuffDecoderCommon::table1_118_emit_[36] = { 0x37, 0x3d, 0x37, 0x41, 0x37, 0x5f, 0x37, 0x62, 0x37, 0x64, 0x37, 0x66, 0x37, 0x67, 0x37, 0x68, 0x37, 0x6c, 0x37, 0x6d, 0x37, 0x6e, 0x37, 0x70, 0x37, 0x72, 0x37, 0x75, 0x37, 0x3a, 0x37, 0x42, 0x37, 0x43, 0x37, 0x44}; -const uint8_t HuffDecoderCommon::table11_119_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_119_emit_[68] = { 0x37, 0x45, 0x37, 0x46, 0x37, 0x47, 0x37, 0x48, 0x37, 0x49, 0x37, 0x4a, 0x37, 0x4b, 0x37, 0x4c, 0x37, 0x4d, 0x37, 0x4e, 0x37, 0x4f, 0x37, 0x50, 0x37, 0x51, 0x37, 0x52, 0x37, 0x53, 0x37, 0x54, 0x37, 0x55, 0x37, 0x56, 0x37, 0x57, 0x37, 0x59, 0x37, 0x6a, 0x37, 0x6b, 0x37, 0x71, 0x37, 0x76, 0x37, 0x77, 0x37, 0x78, 0x37, 0x79, 0x37, 0x7a, 0x37, 0x26, 0x37, 0x2a, 0x37, 0x2c, 0x37, 0x3b, 0x37, 0x58, 0x37, 0x5a}; -const uint8_t HuffDecoderCommon::table11_120_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_120_emit_[16] = { 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x61, 0x38, 0x63, 0x38, 0x65, 0x38, 0x69, 0x38, 0x6f}; -const uint8_t HuffDecoderCommon::table11_121_emit_[27] = { +const uint8_t HuffDecoderCommon::table1_121_emit_[27] = { 0x38, 0x73, 0x38, 0x74, 0x38, 0x20, 0x38, 0x25, 0x38, 0x2d, 0x38, 0x2e, 0x38, 0x2f, 0x38, 0x33, 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, 0x38, 0x38, 0x39}; -const uint16_t HuffDecoderCommon::table11_121_inner_[15] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0065}; -const uint8_t HuffDecoderCommon::table11_122_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_121_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x040c, 0x048c, 0x050c, 0x058c, 0x060c, 0x064c}; +const uint8_t HuffDecoderCommon::table1_122_emit_[36] = { 0x38, 0x3d, 0x38, 0x41, 0x38, 0x5f, 0x38, 0x62, 0x38, 0x64, 0x38, 0x66, 0x38, 0x67, 0x38, 0x68, 0x38, 0x6c, 0x38, 0x6d, 0x38, 0x6e, 0x38, 0x70, 0x38, 0x72, 0x38, 0x75, 0x38, 0x3a, 0x38, 0x42, 0x38, 0x43, 0x38, 0x44}; -const uint8_t HuffDecoderCommon::table11_123_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_123_emit_[68] = { 0x38, 0x45, 0x38, 0x46, 0x38, 0x47, 0x38, 0x48, 0x38, 0x49, 0x38, 0x4a, 0x38, 0x4b, 0x38, 0x4c, 0x38, 0x4d, 0x38, 0x4e, 0x38, 0x4f, 0x38, 0x50, 0x38, 0x51, 0x38, 0x52, 0x38, 0x53, 0x38, 0x54, 0x38, 0x55, 0x38, 0x56, 0x38, 0x57, 0x38, 0x59, 0x38, 0x6a, 0x38, 0x6b, 0x38, 0x71, 0x38, 0x76, 0x38, 0x77, 0x38, 0x78, 0x38, 0x79, 0x38, 0x7a, 0x38, 0x26, 0x38, 0x2a, 0x38, 0x2c, 0x38, 0x3b, 0x38, 0x58, 0x38, 0x5a}; -const uint8_t HuffDecoderCommon::table11_124_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_124_emit_[16] = { 0x39, 0x30, 0x39, 0x31, 0x39, 0x32, 0x39, 0x61, 0x39, 0x63, 0x39, 0x65, 0x39, 0x69, 0x39, 0x6f}; -const uint8_t HuffDecoderCommon::table11_125_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_125_emit_[28] = { 0x39, 0x73, 0x39, 0x74, 0x39, 0x20, 0x39, 0x25, 0x39, 0x2d, 0x39, 0x2e, 0x39, 0x2f, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39}; -const uint8_t HuffDecoderCommon::table11_126_emit_[36] = { +const uint16_t HuffDecoderCommon::table1_125_inner_[14] = { + 0x000b, 0x008b, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, + 0x038c, 0x040c, 0x048c, 0x050c, 0x058c, 0x060c, 0x068c}; +const uint8_t HuffDecoderCommon::table1_126_emit_[36] = { 0x39, 0x3d, 0x39, 0x41, 0x39, 0x5f, 0x39, 0x62, 0x39, 0x64, 0x39, 0x66, 0x39, 0x67, 0x39, 0x68, 0x39, 0x6c, 0x39, 0x6d, 0x39, 0x6e, 0x39, 0x70, 0x39, 0x72, 0x39, 0x75, 0x39, 0x3a, 0x39, 0x42, 0x39, 0x43, 0x39, 0x44}; -const uint8_t HuffDecoderCommon::table11_127_emit_[68] = { +const uint8_t HuffDecoderCommon::table1_127_emit_[68] = { 0x39, 0x45, 0x39, 0x46, 0x39, 0x47, 0x39, 0x48, 0x39, 0x49, 0x39, 0x4a, 0x39, 0x4b, 0x39, 0x4c, 0x39, 0x4d, 0x39, 0x4e, 0x39, 0x4f, 0x39, 0x50, 0x39, 0x51, 0x39, 0x52, 0x39, 0x53, 0x39, 0x54, 0x39, 0x55, 0x39, 0x56, 0x39, 0x57, 0x39, 0x59, 0x39, 0x6a, 0x39, 0x6b, 0x39, 0x71, 0x39, 0x76, 0x39, 0x77, 0x39, 0x78, 0x39, 0x79, 0x39, 0x7a, 0x39, 0x26, 0x39, 0x2a, 0x39, 0x2c, 0x39, 0x3b, 0x39, 0x58, 0x39, 0x5a}; -const uint8_t HuffDecoderCommon::table11_128_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_128_emit_[16] = { 0x3d, 0x30, 0x3d, 0x31, 0x3d, 0x32, 0x3d, 0x61, 0x3d, 0x63, 0x3d, 0x65, 0x3d, 0x69, 0x3d, 0x6f}; -const uint8_t HuffDecoderCommon::table11_129_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_129_emit_[28] = { 0x3d, 0x73, 0x3d, 0x74, 0x3d, 0x20, 0x3d, 0x25, 0x3d, 0x2d, 0x3d, 0x2e, 0x3d, 0x2f, 0x3d, 0x33, 0x3d, 0x34, 0x3d, 0x35, 0x3d, 0x36, 0x3d, 0x37, 0x3d, 0x38, 0x3d, 0x39}; -const uint8_t HuffDecoderCommon::table11_130_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_130_emit_[35] = { 0x3d, 0x3d, 0x41, 0x3d, 0x5f, 0x3d, 0x62, 0x3d, 0x64, 0x3d, 0x66, 0x3d, 0x67, 0x3d, 0x68, 0x3d, 0x6c, 0x3d, 0x6d, 0x3d, 0x6e, 0x3d, 0x70, 0x3d, 0x72, 0x3d, 0x75, 0x3d, 0x3a, 0x3d, 0x42, 0x3d, 0x43, 0x3d, 0x44}; -const uint16_t HuffDecoderCommon::table11_130_inner_[19] = { - 0x0000, 0x0001, 0x0005, 0x000d, 0x0015, 0x001d, 0x0025, - 0x002d, 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_131_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_130_inner_[18] = { + 0x000c, 0x004c, 0x00cc, 0x014c, 0x01cc, 0x024c, 0x02cc, 0x034c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_131_emit_[68] = { 0x3d, 0x45, 0x3d, 0x46, 0x3d, 0x47, 0x3d, 0x48, 0x3d, 0x49, 0x3d, 0x4a, 0x3d, 0x4b, 0x3d, 0x4c, 0x3d, 0x4d, 0x3d, 0x4e, 0x3d, 0x4f, 0x3d, 0x50, 0x3d, 0x51, 0x3d, 0x52, 0x3d, 0x53, 0x3d, 0x54, 0x3d, 0x55, 0x3d, 0x56, 0x3d, 0x57, 0x3d, 0x59, 0x3d, 0x6a, 0x3d, 0x6b, 0x3d, 0x71, 0x3d, 0x76, 0x3d, 0x77, 0x3d, 0x78, 0x3d, 0x79, 0x3d, 0x7a, 0x3d, 0x26, 0x3d, 0x2a, 0x3d, 0x2c, 0x3d, 0x3b, 0x3d, 0x58, 0x3d, 0x5a}; -const uint8_t HuffDecoderCommon::table11_132_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_132_emit_[16] = { 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41, 0x61, 0x41, 0x63, 0x41, 0x65, 0x41, 0x69, 0x41, 0x6f}; -const uint8_t HuffDecoderCommon::table11_133_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_133_emit_[28] = { 0x41, 0x73, 0x41, 0x74, 0x41, 0x20, 0x41, 0x25, 0x41, 0x2d, 0x41, 0x2e, 0x41, 0x2f, 0x41, 0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41, 0x37, 0x41, 0x38, 0x41, 0x39}; -const uint8_t HuffDecoderCommon::table11_134_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_134_emit_[35] = { 0x41, 0x3d, 0x41, 0x41, 0x5f, 0x41, 0x62, 0x41, 0x64, 0x41, 0x66, 0x41, 0x67, 0x41, 0x68, 0x41, 0x6c, 0x41, 0x6d, 0x41, 0x6e, 0x41, 0x70, 0x41, 0x72, 0x41, 0x75, 0x41, 0x3a, 0x41, 0x42, 0x41, 0x43, 0x41, 0x44}; -const uint16_t HuffDecoderCommon::table11_134_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x000d, 0x0015, 0x001d, 0x0025, - 0x002d, 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_135_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_134_inner_[18] = { + 0x000c, 0x008c, 0x00cc, 0x014c, 0x01cc, 0x024c, 0x02cc, 0x034c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_135_emit_[68] = { 0x41, 0x45, 0x41, 0x46, 0x41, 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4a, 0x41, 0x4b, 0x41, 0x4c, 0x41, 0x4d, 0x41, 0x4e, 0x41, 0x4f, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x41, 0x59, 0x41, 0x6a, 0x41, 0x6b, 0x41, 0x71, 0x41, 0x76, 0x41, 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7a, 0x41, 0x26, 0x41, 0x2a, 0x41, 0x2c, 0x41, 0x3b, 0x41, 0x58, 0x41, 0x5a}; -const uint8_t HuffDecoderCommon::table11_136_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_136_emit_[16] = { 0x5f, 0x30, 0x5f, 0x31, 0x5f, 0x32, 0x5f, 0x61, 0x5f, 0x63, 0x5f, 0x65, 0x5f, 0x69, 0x5f, 0x6f}; -const uint8_t HuffDecoderCommon::table11_137_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_137_emit_[28] = { 0x5f, 0x73, 0x5f, 0x74, 0x5f, 0x20, 0x5f, 0x25, 0x5f, 0x2d, 0x5f, 0x2e, 0x5f, 0x2f, 0x5f, 0x33, 0x5f, 0x34, 0x5f, 0x35, 0x5f, 0x36, 0x5f, 0x37, 0x5f, 0x38, 0x5f, 0x39}; -const uint8_t HuffDecoderCommon::table11_138_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_138_emit_[35] = { 0x5f, 0x3d, 0x5f, 0x41, 0x5f, 0x5f, 0x62, 0x5f, 0x64, 0x5f, 0x66, 0x5f, 0x67, 0x5f, 0x68, 0x5f, 0x6c, 0x5f, 0x6d, 0x5f, 0x6e, 0x5f, 0x70, 0x5f, 0x72, 0x5f, 0x75, 0x5f, 0x3a, 0x5f, 0x42, 0x5f, 0x43, 0x5f, 0x44}; -const uint16_t HuffDecoderCommon::table11_138_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0015, 0x001d, 0x0025, - 0x002d, 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_139_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_138_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x014c, 0x01cc, 0x024c, 0x02cc, 0x034c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_139_emit_[68] = { 0x5f, 0x45, 0x5f, 0x46, 0x5f, 0x47, 0x5f, 0x48, 0x5f, 0x49, 0x5f, 0x4a, 0x5f, 0x4b, 0x5f, 0x4c, 0x5f, 0x4d, 0x5f, 0x4e, 0x5f, 0x4f, 0x5f, 0x50, 0x5f, 0x51, 0x5f, 0x52, 0x5f, 0x53, 0x5f, 0x54, 0x5f, 0x55, 0x5f, 0x56, 0x5f, 0x57, 0x5f, 0x59, 0x5f, 0x6a, 0x5f, 0x6b, 0x5f, 0x71, 0x5f, 0x76, 0x5f, 0x77, 0x5f, 0x78, 0x5f, 0x79, 0x5f, 0x7a, 0x5f, 0x26, 0x5f, 0x2a, 0x5f, 0x2c, 0x5f, 0x3b, 0x5f, 0x58, 0x5f, 0x5a}; -const uint8_t HuffDecoderCommon::table11_140_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_140_emit_[16] = { 0x62, 0x30, 0x62, 0x31, 0x62, 0x32, 0x62, 0x61, 0x62, 0x63, 0x62, 0x65, 0x62, 0x69, 0x62, 0x6f}; -const uint8_t HuffDecoderCommon::table11_141_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_141_emit_[28] = { 0x62, 0x73, 0x62, 0x74, 0x62, 0x20, 0x62, 0x25, 0x62, 0x2d, 0x62, 0x2e, 0x62, 0x2f, 0x62, 0x33, 0x62, 0x34, 0x62, 0x35, 0x62, 0x36, 0x62, 0x37, 0x62, 0x38, 0x62, 0x39}; -const uint8_t HuffDecoderCommon::table11_142_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_142_emit_[35] = { 0x62, 0x3d, 0x62, 0x41, 0x62, 0x5f, 0x62, 0x62, 0x64, 0x62, 0x66, 0x62, 0x67, 0x62, 0x68, 0x62, 0x6c, 0x62, 0x6d, 0x62, 0x6e, 0x62, 0x70, 0x62, 0x72, 0x62, 0x75, 0x62, 0x3a, 0x62, 0x42, 0x62, 0x43, 0x62, 0x44}; -const uint16_t HuffDecoderCommon::table11_142_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x001d, 0x0025, - 0x002d, 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_143_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_142_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x01cc, 0x024c, 0x02cc, 0x034c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_143_emit_[68] = { 0x62, 0x45, 0x62, 0x46, 0x62, 0x47, 0x62, 0x48, 0x62, 0x49, 0x62, 0x4a, 0x62, 0x4b, 0x62, 0x4c, 0x62, 0x4d, 0x62, 0x4e, 0x62, 0x4f, 0x62, 0x50, 0x62, 0x51, 0x62, 0x52, 0x62, 0x53, 0x62, 0x54, 0x62, 0x55, 0x62, 0x56, 0x62, 0x57, 0x62, 0x59, 0x62, 0x6a, 0x62, 0x6b, 0x62, 0x71, 0x62, 0x76, 0x62, 0x77, 0x62, 0x78, 0x62, 0x79, 0x62, 0x7a, 0x62, 0x26, 0x62, 0x2a, 0x62, 0x2c, 0x62, 0x3b, 0x62, 0x58, 0x62, 0x5a}; -const uint8_t HuffDecoderCommon::table11_144_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_144_emit_[16] = { 0x64, 0x30, 0x64, 0x31, 0x64, 0x32, 0x64, 0x61, 0x64, 0x63, 0x64, 0x65, 0x64, 0x69, 0x64, 0x6f}; -const uint8_t HuffDecoderCommon::table11_145_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_145_emit_[28] = { 0x64, 0x73, 0x64, 0x74, 0x64, 0x20, 0x64, 0x25, 0x64, 0x2d, 0x64, 0x2e, 0x64, 0x2f, 0x64, 0x33, 0x64, 0x34, 0x64, 0x35, 0x64, 0x36, 0x64, 0x37, 0x64, 0x38, 0x64, 0x39}; -const uint8_t HuffDecoderCommon::table11_146_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_146_emit_[35] = { 0x64, 0x3d, 0x64, 0x41, 0x64, 0x5f, 0x64, 0x62, 0x64, 0x64, 0x66, 0x64, 0x67, 0x64, 0x68, 0x64, 0x6c, 0x64, 0x6d, 0x64, 0x6e, 0x64, 0x70, 0x64, 0x72, 0x64, 0x75, 0x64, 0x3a, 0x64, 0x42, 0x64, 0x43, 0x64, 0x44}; -const uint16_t HuffDecoderCommon::table11_146_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0025, - 0x002d, 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_147_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_146_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x024c, 0x02cc, 0x034c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_147_emit_[68] = { 0x64, 0x45, 0x64, 0x46, 0x64, 0x47, 0x64, 0x48, 0x64, 0x49, 0x64, 0x4a, 0x64, 0x4b, 0x64, 0x4c, 0x64, 0x4d, 0x64, 0x4e, 0x64, 0x4f, 0x64, 0x50, 0x64, 0x51, 0x64, 0x52, 0x64, 0x53, 0x64, 0x54, 0x64, 0x55, 0x64, 0x56, 0x64, 0x57, 0x64, 0x59, 0x64, 0x6a, 0x64, 0x6b, 0x64, 0x71, 0x64, 0x76, 0x64, 0x77, 0x64, 0x78, 0x64, 0x79, 0x64, 0x7a, 0x64, 0x26, 0x64, 0x2a, 0x64, 0x2c, 0x64, 0x3b, 0x64, 0x58, 0x64, 0x5a}; -const uint8_t HuffDecoderCommon::table11_148_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_148_emit_[16] = { 0x66, 0x30, 0x66, 0x31, 0x66, 0x32, 0x66, 0x61, 0x66, 0x63, 0x66, 0x65, 0x66, 0x69, 0x66, 0x6f}; -const uint8_t HuffDecoderCommon::table11_149_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_149_emit_[28] = { 0x66, 0x73, 0x66, 0x74, 0x66, 0x20, 0x66, 0x25, 0x66, 0x2d, 0x66, 0x2e, 0x66, 0x2f, 0x66, 0x33, 0x66, 0x34, 0x66, 0x35, 0x66, 0x36, 0x66, 0x37, 0x66, 0x38, 0x66, 0x39}; -const uint8_t HuffDecoderCommon::table11_150_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_150_emit_[35] = { 0x66, 0x3d, 0x66, 0x41, 0x66, 0x5f, 0x66, 0x62, 0x66, 0x64, 0x66, 0x66, 0x67, 0x66, 0x68, 0x66, 0x6c, 0x66, 0x6d, 0x66, 0x6e, 0x66, 0x70, 0x66, 0x72, 0x66, 0x75, 0x66, 0x3a, 0x66, 0x42, 0x66, 0x43, 0x66, 0x44}; -const uint16_t HuffDecoderCommon::table11_150_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x002d, 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_151_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_150_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x02cc, 0x034c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_151_emit_[68] = { 0x66, 0x45, 0x66, 0x46, 0x66, 0x47, 0x66, 0x48, 0x66, 0x49, 0x66, 0x4a, 0x66, 0x4b, 0x66, 0x4c, 0x66, 0x4d, 0x66, 0x4e, 0x66, 0x4f, 0x66, 0x50, 0x66, 0x51, 0x66, 0x52, 0x66, 0x53, 0x66, 0x54, 0x66, 0x55, 0x66, 0x56, 0x66, 0x57, 0x66, 0x59, 0x66, 0x6a, 0x66, 0x6b, 0x66, 0x71, 0x66, 0x76, 0x66, 0x77, 0x66, 0x78, 0x66, 0x79, 0x66, 0x7a, 0x66, 0x26, 0x66, 0x2a, 0x66, 0x2c, 0x66, 0x3b, 0x66, 0x58, 0x66, 0x5a}; -const uint8_t HuffDecoderCommon::table11_152_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_152_emit_[16] = { 0x67, 0x30, 0x67, 0x31, 0x67, 0x32, 0x67, 0x61, 0x67, 0x63, 0x67, 0x65, 0x67, 0x69, 0x67, 0x6f}; -const uint8_t HuffDecoderCommon::table11_153_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_153_emit_[28] = { 0x67, 0x73, 0x67, 0x74, 0x67, 0x20, 0x67, 0x25, 0x67, 0x2d, 0x67, 0x2e, 0x67, 0x2f, 0x67, 0x33, 0x67, 0x34, 0x67, 0x35, 0x67, 0x36, 0x67, 0x37, 0x67, 0x38, 0x67, 0x39}; -const uint8_t HuffDecoderCommon::table11_154_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_154_emit_[35] = { 0x67, 0x3d, 0x67, 0x41, 0x67, 0x5f, 0x67, 0x62, 0x67, 0x64, 0x67, 0x66, 0x67, 0x67, 0x68, 0x67, 0x6c, 0x67, 0x6d, 0x67, 0x6e, 0x67, 0x70, 0x67, 0x72, 0x67, 0x75, 0x67, 0x3a, 0x67, 0x42, 0x67, 0x43, 0x67, 0x44}; -const uint16_t HuffDecoderCommon::table11_154_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_155_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_154_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x034c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_155_emit_[68] = { 0x67, 0x45, 0x67, 0x46, 0x67, 0x47, 0x67, 0x48, 0x67, 0x49, 0x67, 0x4a, 0x67, 0x4b, 0x67, 0x4c, 0x67, 0x4d, 0x67, 0x4e, 0x67, 0x4f, 0x67, 0x50, 0x67, 0x51, 0x67, 0x52, 0x67, 0x53, 0x67, 0x54, 0x67, 0x55, 0x67, 0x56, 0x67, 0x57, 0x67, 0x59, 0x67, 0x6a, 0x67, 0x6b, 0x67, 0x71, 0x67, 0x76, 0x67, 0x77, 0x67, 0x78, 0x67, 0x79, 0x67, 0x7a, 0x67, 0x26, 0x67, 0x2a, 0x67, 0x2c, 0x67, 0x3b, 0x67, 0x58, 0x67, 0x5a}; -const uint8_t HuffDecoderCommon::table11_156_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_156_emit_[16] = { 0x68, 0x30, 0x68, 0x31, 0x68, 0x32, 0x68, 0x61, 0x68, 0x63, 0x68, 0x65, 0x68, 0x69, 0x68, 0x6f}; -const uint8_t HuffDecoderCommon::table11_157_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_157_emit_[28] = { 0x68, 0x73, 0x68, 0x74, 0x68, 0x20, 0x68, 0x25, 0x68, 0x2d, 0x68, 0x2e, 0x68, 0x2f, 0x68, 0x33, 0x68, 0x34, 0x68, 0x35, 0x68, 0x36, 0x68, 0x37, 0x68, 0x38, 0x68, 0x39}; -const uint8_t HuffDecoderCommon::table11_158_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_158_emit_[35] = { 0x68, 0x3d, 0x68, 0x41, 0x68, 0x5f, 0x68, 0x62, 0x68, 0x64, 0x68, 0x66, 0x68, 0x67, 0x68, 0x68, 0x6c, 0x68, 0x6d, 0x68, 0x6e, 0x68, 0x70, 0x68, 0x72, 0x68, 0x75, 0x68, 0x3a, 0x68, 0x42, 0x68, 0x43, 0x68, 0x44}; -const uint16_t HuffDecoderCommon::table11_158_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_159_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_158_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x03cc, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_159_emit_[68] = { 0x68, 0x45, 0x68, 0x46, 0x68, 0x47, 0x68, 0x48, 0x68, 0x49, 0x68, 0x4a, 0x68, 0x4b, 0x68, 0x4c, 0x68, 0x4d, 0x68, 0x4e, 0x68, 0x4f, 0x68, 0x50, 0x68, 0x51, 0x68, 0x52, 0x68, 0x53, 0x68, 0x54, 0x68, 0x55, 0x68, 0x56, 0x68, 0x57, 0x68, 0x59, 0x68, 0x6a, 0x68, 0x6b, 0x68, 0x71, 0x68, 0x76, 0x68, 0x77, 0x68, 0x78, 0x68, 0x79, 0x68, 0x7a, 0x68, 0x26, 0x68, 0x2a, 0x68, 0x2c, 0x68, 0x3b, 0x68, 0x58, 0x68, 0x5a}; -const uint8_t HuffDecoderCommon::table11_160_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_160_emit_[16] = { 0x6c, 0x30, 0x6c, 0x31, 0x6c, 0x32, 0x6c, 0x61, 0x6c, 0x63, 0x6c, 0x65, 0x6c, 0x69, 0x6c, 0x6f}; -const uint8_t HuffDecoderCommon::table11_161_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_161_emit_[28] = { 0x6c, 0x73, 0x6c, 0x74, 0x6c, 0x20, 0x6c, 0x25, 0x6c, 0x2d, 0x6c, 0x2e, 0x6c, 0x2f, 0x6c, 0x33, 0x6c, 0x34, 0x6c, 0x35, 0x6c, 0x36, 0x6c, 0x37, 0x6c, 0x38, 0x6c, 0x39}; -const uint8_t HuffDecoderCommon::table11_162_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_162_emit_[35] = { 0x6c, 0x3d, 0x6c, 0x41, 0x6c, 0x5f, 0x6c, 0x62, 0x6c, 0x64, 0x6c, 0x66, 0x6c, 0x67, 0x6c, 0x68, 0x6c, 0x6c, 0x6d, 0x6c, 0x6e, 0x6c, 0x70, 0x6c, 0x72, 0x6c, 0x75, 0x6c, 0x3a, 0x6c, 0x42, 0x6c, 0x43, 0x6c, 0x44}; -const uint16_t HuffDecoderCommon::table11_162_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x0041, 0x0045, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_163_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_162_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x040c, + 0x044c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_163_emit_[68] = { 0x6c, 0x45, 0x6c, 0x46, 0x6c, 0x47, 0x6c, 0x48, 0x6c, 0x49, 0x6c, 0x4a, 0x6c, 0x4b, 0x6c, 0x4c, 0x6c, 0x4d, 0x6c, 0x4e, 0x6c, 0x4f, 0x6c, 0x50, 0x6c, 0x51, 0x6c, 0x52, 0x6c, 0x53, 0x6c, 0x54, 0x6c, 0x55, 0x6c, 0x56, 0x6c, 0x57, 0x6c, 0x59, 0x6c, 0x6a, 0x6c, 0x6b, 0x6c, 0x71, 0x6c, 0x76, 0x6c, 0x77, 0x6c, 0x78, 0x6c, 0x79, 0x6c, 0x7a, 0x6c, 0x26, 0x6c, 0x2a, 0x6c, 0x2c, 0x6c, 0x3b, 0x6c, 0x58, 0x6c, 0x5a}; -const uint8_t HuffDecoderCommon::table11_164_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_164_emit_[16] = { 0x6d, 0x30, 0x6d, 0x31, 0x6d, 0x32, 0x6d, 0x61, 0x6d, 0x63, 0x6d, 0x65, 0x6d, 0x69, 0x6d, 0x6f}; -const uint8_t HuffDecoderCommon::table11_165_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_165_emit_[28] = { 0x6d, 0x73, 0x6d, 0x74, 0x6d, 0x20, 0x6d, 0x25, 0x6d, 0x2d, 0x6d, 0x2e, 0x6d, 0x2f, 0x6d, 0x33, 0x6d, 0x34, 0x6d, 0x35, 0x6d, 0x36, 0x6d, 0x37, 0x6d, 0x38, 0x6d, 0x39}; -const uint8_t HuffDecoderCommon::table11_166_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_166_emit_[35] = { 0x6d, 0x3d, 0x6d, 0x41, 0x6d, 0x5f, 0x6d, 0x62, 0x6d, 0x64, 0x6d, 0x66, 0x6d, 0x67, 0x6d, 0x68, 0x6d, 0x6c, 0x6d, 0x6d, 0x6e, 0x6d, 0x70, 0x6d, 0x72, 0x6d, 0x75, 0x6d, 0x3a, 0x6d, 0x42, 0x6d, 0x43, 0x6d, 0x44}; -const uint16_t HuffDecoderCommon::table11_166_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x0041, 0x0049, 0x004d, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_167_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_166_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x040c, + 0x048c, 0x04cc, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_167_emit_[68] = { 0x6d, 0x45, 0x6d, 0x46, 0x6d, 0x47, 0x6d, 0x48, 0x6d, 0x49, 0x6d, 0x4a, 0x6d, 0x4b, 0x6d, 0x4c, 0x6d, 0x4d, 0x6d, 0x4e, 0x6d, 0x4f, 0x6d, 0x50, 0x6d, 0x51, 0x6d, 0x52, 0x6d, 0x53, 0x6d, 0x54, 0x6d, 0x55, 0x6d, 0x56, 0x6d, 0x57, 0x6d, 0x59, 0x6d, 0x6a, 0x6d, 0x6b, 0x6d, 0x71, 0x6d, 0x76, 0x6d, 0x77, 0x6d, 0x78, 0x6d, 0x79, 0x6d, 0x7a, 0x6d, 0x26, 0x6d, 0x2a, 0x6d, 0x2c, 0x6d, 0x3b, 0x6d, 0x58, 0x6d, 0x5a}; -const uint8_t HuffDecoderCommon::table11_168_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_168_emit_[16] = { 0x6e, 0x30, 0x6e, 0x31, 0x6e, 0x32, 0x6e, 0x61, 0x6e, 0x63, 0x6e, 0x65, 0x6e, 0x69, 0x6e, 0x6f}; -const uint8_t HuffDecoderCommon::table11_169_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_169_emit_[28] = { 0x6e, 0x73, 0x6e, 0x74, 0x6e, 0x20, 0x6e, 0x25, 0x6e, 0x2d, 0x6e, 0x2e, 0x6e, 0x2f, 0x6e, 0x33, 0x6e, 0x34, 0x6e, 0x35, 0x6e, 0x36, 0x6e, 0x37, 0x6e, 0x38, 0x6e, 0x39}; -const uint8_t HuffDecoderCommon::table11_170_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_170_emit_[35] = { 0x6e, 0x3d, 0x6e, 0x41, 0x6e, 0x5f, 0x6e, 0x62, 0x6e, 0x64, 0x6e, 0x66, 0x6e, 0x67, 0x6e, 0x68, 0x6e, 0x6c, 0x6e, 0x6d, 0x6e, 0x6e, 0x70, 0x6e, 0x72, 0x6e, 0x75, 0x6e, 0x3a, 0x6e, 0x42, 0x6e, 0x43, 0x6e, 0x44}; -const uint16_t HuffDecoderCommon::table11_170_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x0041, 0x0049, 0x0051, 0x0055, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_171_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_170_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x040c, + 0x048c, 0x050c, 0x054c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_171_emit_[68] = { 0x6e, 0x45, 0x6e, 0x46, 0x6e, 0x47, 0x6e, 0x48, 0x6e, 0x49, 0x6e, 0x4a, 0x6e, 0x4b, 0x6e, 0x4c, 0x6e, 0x4d, 0x6e, 0x4e, 0x6e, 0x4f, 0x6e, 0x50, 0x6e, 0x51, 0x6e, 0x52, 0x6e, 0x53, 0x6e, 0x54, 0x6e, 0x55, 0x6e, 0x56, 0x6e, 0x57, 0x6e, 0x59, 0x6e, 0x6a, 0x6e, 0x6b, 0x6e, 0x71, 0x6e, 0x76, 0x6e, 0x77, 0x6e, 0x78, 0x6e, 0x79, 0x6e, 0x7a, 0x6e, 0x26, 0x6e, 0x2a, 0x6e, 0x2c, 0x6e, 0x3b, 0x6e, 0x58, 0x6e, 0x5a}; -const uint8_t HuffDecoderCommon::table11_172_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_172_emit_[16] = { 0x70, 0x30, 0x70, 0x31, 0x70, 0x32, 0x70, 0x61, 0x70, 0x63, 0x70, 0x65, 0x70, 0x69, 0x70, 0x6f}; -const uint8_t HuffDecoderCommon::table11_173_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_173_emit_[28] = { 0x70, 0x73, 0x70, 0x74, 0x70, 0x20, 0x70, 0x25, 0x70, 0x2d, 0x70, 0x2e, 0x70, 0x2f, 0x70, 0x33, 0x70, 0x34, 0x70, 0x35, 0x70, 0x36, 0x70, 0x37, 0x70, 0x38, 0x70, 0x39}; -const uint8_t HuffDecoderCommon::table11_174_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_174_emit_[35] = { 0x70, 0x3d, 0x70, 0x41, 0x70, 0x5f, 0x70, 0x62, 0x70, 0x64, 0x70, 0x66, 0x70, 0x67, 0x70, 0x68, 0x70, 0x6c, 0x70, 0x6d, 0x70, 0x6e, 0x70, 0x70, 0x72, 0x70, 0x75, 0x70, 0x3a, 0x70, 0x42, 0x70, 0x43, 0x70, 0x44}; -const uint16_t HuffDecoderCommon::table11_174_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x005d, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_175_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_174_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x040c, + 0x048c, 0x050c, 0x058c, 0x05cc, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_175_emit_[68] = { 0x70, 0x45, 0x70, 0x46, 0x70, 0x47, 0x70, 0x48, 0x70, 0x49, 0x70, 0x4a, 0x70, 0x4b, 0x70, 0x4c, 0x70, 0x4d, 0x70, 0x4e, 0x70, 0x4f, 0x70, 0x50, 0x70, 0x51, 0x70, 0x52, 0x70, 0x53, 0x70, 0x54, 0x70, 0x55, 0x70, 0x56, 0x70, 0x57, 0x70, 0x59, 0x70, 0x6a, 0x70, 0x6b, 0x70, 0x71, 0x70, 0x76, 0x70, 0x77, 0x70, 0x78, 0x70, 0x79, 0x70, 0x7a, 0x70, 0x26, 0x70, 0x2a, 0x70, 0x2c, 0x70, 0x3b, 0x70, 0x58, 0x70, 0x5a}; -const uint8_t HuffDecoderCommon::table11_176_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_176_emit_[16] = { 0x72, 0x30, 0x72, 0x31, 0x72, 0x32, 0x72, 0x61, 0x72, 0x63, 0x72, 0x65, 0x72, 0x69, 0x72, 0x6f}; -const uint8_t HuffDecoderCommon::table11_177_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_177_emit_[28] = { 0x72, 0x73, 0x72, 0x74, 0x72, 0x20, 0x72, 0x25, 0x72, 0x2d, 0x72, 0x2e, 0x72, 0x2f, 0x72, 0x33, 0x72, 0x34, 0x72, 0x35, 0x72, 0x36, 0x72, 0x37, 0x72, 0x38, 0x72, 0x39}; -const uint8_t HuffDecoderCommon::table11_178_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_178_emit_[35] = { 0x72, 0x3d, 0x72, 0x41, 0x72, 0x5f, 0x72, 0x62, 0x72, 0x64, 0x72, 0x66, 0x72, 0x67, 0x72, 0x68, 0x72, 0x6c, 0x72, 0x6d, 0x72, 0x6e, 0x72, 0x70, 0x72, 0x72, 0x75, 0x72, 0x3a, 0x72, 0x42, 0x72, 0x43, 0x72, 0x44}; -const uint16_t HuffDecoderCommon::table11_178_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, - 0x0065, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_179_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_178_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x040c, + 0x048c, 0x050c, 0x058c, 0x060c, 0x064c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_179_emit_[68] = { 0x72, 0x45, 0x72, 0x46, 0x72, 0x47, 0x72, 0x48, 0x72, 0x49, 0x72, 0x4a, 0x72, 0x4b, 0x72, 0x4c, 0x72, 0x4d, 0x72, 0x4e, 0x72, 0x4f, 0x72, 0x50, 0x72, 0x51, 0x72, 0x52, 0x72, 0x53, 0x72, 0x54, 0x72, 0x55, 0x72, 0x56, 0x72, 0x57, 0x72, 0x59, 0x72, 0x6a, 0x72, 0x6b, 0x72, 0x71, 0x72, 0x76, 0x72, 0x77, 0x72, 0x78, 0x72, 0x79, 0x72, 0x7a, 0x72, 0x26, 0x72, 0x2a, 0x72, 0x2c, 0x72, 0x3b, 0x72, 0x58, 0x72, 0x5a}; -const uint8_t HuffDecoderCommon::table11_180_emit_[16] = { +const uint8_t HuffDecoderCommon::table1_180_emit_[16] = { 0x75, 0x30, 0x75, 0x31, 0x75, 0x32, 0x75, 0x61, 0x75, 0x63, 0x75, 0x65, 0x75, 0x69, 0x75, 0x6f}; -const uint8_t HuffDecoderCommon::table11_181_emit_[28] = { +const uint8_t HuffDecoderCommon::table1_181_emit_[28] = { 0x75, 0x73, 0x75, 0x74, 0x75, 0x20, 0x75, 0x25, 0x75, 0x2d, 0x75, 0x2e, 0x75, 0x2f, 0x75, 0x33, 0x75, 0x34, 0x75, 0x35, 0x75, 0x36, 0x75, 0x37, 0x75, 0x38, 0x75, 0x39}; -const uint8_t HuffDecoderCommon::table11_182_emit_[35] = { +const uint8_t HuffDecoderCommon::table1_182_emit_[35] = { 0x75, 0x3d, 0x75, 0x41, 0x75, 0x5f, 0x75, 0x62, 0x75, 0x64, 0x75, 0x66, 0x75, 0x67, 0x75, 0x68, 0x75, 0x6c, 0x75, 0x6d, 0x75, 0x6e, 0x75, 0x70, 0x75, 0x72, 0x75, 0x75, 0x3a, 0x75, 0x42, 0x75, 0x43, 0x75, 0x44}; -const uint16_t HuffDecoderCommon::table11_182_inner_[19] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, - 0x0031, 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, - 0x0069, 0x006d, 0x0075, 0x007d, 0x0085}; -const uint8_t HuffDecoderCommon::table11_183_emit_[68] = { +const uint16_t HuffDecoderCommon::table1_182_inner_[18] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, 0x040c, + 0x048c, 0x050c, 0x058c, 0x060c, 0x068c, 0x06cd, 0x074d, 0x07cd, 0x084d}; +const uint8_t HuffDecoderCommon::table1_183_emit_[68] = { 0x75, 0x45, 0x75, 0x46, 0x75, 0x47, 0x75, 0x48, 0x75, 0x49, 0x75, 0x4a, 0x75, 0x4b, 0x75, 0x4c, 0x75, 0x4d, 0x75, 0x4e, 0x75, 0x4f, 0x75, 0x50, 0x75, 0x51, 0x75, 0x52, 0x75, 0x53, 0x75, 0x54, 0x75, 0x55, 0x75, 0x56, 0x75, 0x57, 0x75, 0x59, 0x75, 0x6a, 0x75, 0x6b, 0x75, 0x71, 0x75, 0x76, 0x75, 0x77, 0x75, 0x78, 0x75, 0x79, 0x75, 0x7a, 0x75, 0x26, 0x75, 0x2a, 0x75, 0x2c, 0x75, 0x3b, 0x75, 0x58, 0x75, 0x5a}; -const uint8_t HuffDecoderCommon::table11_184_emit_[44] = { +const uint8_t HuffDecoderCommon::table1_184_emit_[44] = { 0x3a, 0x30, 0x3a, 0x31, 0x3a, 0x32, 0x3a, 0x61, 0x3a, 0x63, 0x3a, 0x65, 0x3a, 0x69, 0x3a, 0x6f, 0x3a, 0x73, 0x3a, 0x74, 0x3a, 0x20, 0x3a, 0x25, 0x3a, 0x2d, 0x3a, 0x2e, 0x3a, 0x2f, 0x3a, 0x33, 0x3a, 0x34, 0x3a, 0x35, 0x3a, 0x36, 0x3a, 0x37, 0x3a, 0x38, 0x3a, 0x39}; -const uint8_t HuffDecoderCommon::table11_185_emit_[91] = { +const uint16_t HuffDecoderCommon::table1_184_inner_[22] = { + 0x000c, 0x008c, 0x010c, 0x018c, 0x020c, 0x028c, 0x030c, 0x038c, + 0x040c, 0x048c, 0x050d, 0x058d, 0x060d, 0x068d, 0x070d, 0x078d, + 0x080d, 0x088d, 0x090d, 0x098d, 0x0a0d, 0x0a8d}; +const uint8_t HuffDecoderCommon::table1_184_outer_[64] = { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, + 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21}; +const uint8_t HuffDecoderCommon::table1_185_emit_[91] = { 0x3a, 0x3d, 0x3a, 0x41, 0x3a, 0x5f, 0x3a, 0x62, 0x3a, 0x64, 0x3a, 0x66, 0x3a, 0x67, 0x3a, 0x68, 0x3a, 0x6c, 0x3a, 0x6d, 0x3a, 0x6e, 0x3a, 0x70, 0x3a, 0x72, 0x3a, 0x75, 0x3a, 0x3a, 0x42, 0x3a, 0x43, 0x3a, 0x44, 0x3a, @@ -2975,19 +3008,24 @@ const uint8_t HuffDecoderCommon::table11_185_emit_[91] = { 0x51, 0x3a, 0x52, 0x3a, 0x53, 0x3a, 0x54, 0x3a, 0x55, 0x3a, 0x56, 0x3a, 0x57, 0x3a, 0x59, 0x3a, 0x6a, 0x3a, 0x6b, 0x3a, 0x71, 0x3a, 0x76, 0x3a, 0x77, 0x3a, 0x78, 0x3a, 0x79, 0x3a, 0x7a}; -const uint16_t HuffDecoderCommon::table11_185_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0075, 0x007d, 0x0085, 0x008d, 0x0095, 0x009d, 0x00a5, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_186_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_185_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x074e, + 0x07ce, 0x084e, 0x08ce, 0x094e, 0x09ce, 0x0a4e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_185_outer_[64] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 46, 46}; +const uint8_t HuffDecoderCommon::table1_186_emit_[44] = { 0x42, 0x30, 0x42, 0x31, 0x42, 0x32, 0x42, 0x61, 0x42, 0x63, 0x42, 0x65, 0x42, 0x69, 0x42, 0x6f, 0x42, 0x73, 0x42, 0x74, 0x42, 0x20, 0x42, 0x25, 0x42, 0x2d, 0x42, 0x2e, 0x42, 0x2f, 0x42, 0x33, 0x42, 0x34, 0x42, 0x35, 0x42, 0x36, 0x42, 0x37, 0x42, 0x38, 0x42, 0x39}; -const uint8_t HuffDecoderCommon::table11_187_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_187_emit_[91] = { 0x42, 0x3d, 0x42, 0x41, 0x42, 0x5f, 0x42, 0x62, 0x42, 0x64, 0x42, 0x66, 0x42, 0x67, 0x42, 0x68, 0x42, 0x6c, 0x42, 0x6d, 0x42, 0x6e, 0x42, 0x70, 0x42, 0x72, 0x42, 0x75, 0x42, 0x3a, 0x42, 0x42, 0x43, 0x42, 0x44, 0x42, @@ -2996,19 +3034,19 @@ const uint8_t HuffDecoderCommon::table11_187_emit_[91] = { 0x51, 0x42, 0x52, 0x42, 0x53, 0x42, 0x54, 0x42, 0x55, 0x42, 0x56, 0x42, 0x57, 0x42, 0x59, 0x42, 0x6a, 0x42, 0x6b, 0x42, 0x71, 0x42, 0x76, 0x42, 0x77, 0x42, 0x78, 0x42, 0x79, 0x42, 0x7a}; -const uint16_t HuffDecoderCommon::table11_187_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x007d, 0x0085, 0x008d, 0x0095, 0x009d, 0x00a5, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_188_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_187_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x07ce, 0x084e, 0x08ce, 0x094e, 0x09ce, 0x0a4e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_188_emit_[44] = { 0x43, 0x30, 0x43, 0x31, 0x43, 0x32, 0x43, 0x61, 0x43, 0x63, 0x43, 0x65, 0x43, 0x69, 0x43, 0x6f, 0x43, 0x73, 0x43, 0x74, 0x43, 0x20, 0x43, 0x25, 0x43, 0x2d, 0x43, 0x2e, 0x43, 0x2f, 0x43, 0x33, 0x43, 0x34, 0x43, 0x35, 0x43, 0x36, 0x43, 0x37, 0x43, 0x38, 0x43, 0x39}; -const uint8_t HuffDecoderCommon::table11_189_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_189_emit_[91] = { 0x43, 0x3d, 0x43, 0x41, 0x43, 0x5f, 0x43, 0x62, 0x43, 0x64, 0x43, 0x66, 0x43, 0x67, 0x43, 0x68, 0x43, 0x6c, 0x43, 0x6d, 0x43, 0x6e, 0x43, 0x70, 0x43, 0x72, 0x43, 0x75, 0x43, 0x3a, 0x43, 0x42, 0x43, 0x43, 0x44, 0x43, @@ -3017,19 +3055,19 @@ const uint8_t HuffDecoderCommon::table11_189_emit_[91] = { 0x51, 0x43, 0x52, 0x43, 0x53, 0x43, 0x54, 0x43, 0x55, 0x43, 0x56, 0x43, 0x57, 0x43, 0x59, 0x43, 0x6a, 0x43, 0x6b, 0x43, 0x71, 0x43, 0x76, 0x43, 0x77, 0x43, 0x78, 0x43, 0x79, 0x43, 0x7a}; -const uint16_t HuffDecoderCommon::table11_189_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0085, 0x008d, 0x0095, 0x009d, 0x00a5, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_190_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_189_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x084e, 0x08ce, 0x094e, 0x09ce, 0x0a4e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_190_emit_[44] = { 0x44, 0x30, 0x44, 0x31, 0x44, 0x32, 0x44, 0x61, 0x44, 0x63, 0x44, 0x65, 0x44, 0x69, 0x44, 0x6f, 0x44, 0x73, 0x44, 0x74, 0x44, 0x20, 0x44, 0x25, 0x44, 0x2d, 0x44, 0x2e, 0x44, 0x2f, 0x44, 0x33, 0x44, 0x34, 0x44, 0x35, 0x44, 0x36, 0x44, 0x37, 0x44, 0x38, 0x44, 0x39}; -const uint8_t HuffDecoderCommon::table11_191_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_191_emit_[91] = { 0x44, 0x3d, 0x44, 0x41, 0x44, 0x5f, 0x44, 0x62, 0x44, 0x64, 0x44, 0x66, 0x44, 0x67, 0x44, 0x68, 0x44, 0x6c, 0x44, 0x6d, 0x44, 0x6e, 0x44, 0x70, 0x44, 0x72, 0x44, 0x75, 0x44, 0x3a, 0x44, 0x42, 0x44, 0x43, 0x44, 0x44, @@ -3038,19 +3076,19 @@ const uint8_t HuffDecoderCommon::table11_191_emit_[91] = { 0x51, 0x44, 0x52, 0x44, 0x53, 0x44, 0x54, 0x44, 0x55, 0x44, 0x56, 0x44, 0x57, 0x44, 0x59, 0x44, 0x6a, 0x44, 0x6b, 0x44, 0x71, 0x44, 0x76, 0x44, 0x77, 0x44, 0x78, 0x44, 0x79, 0x44, 0x7a}; -const uint16_t HuffDecoderCommon::table11_191_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x008d, 0x0095, 0x009d, 0x00a5, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_192_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_191_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x08ce, 0x094e, 0x09ce, 0x0a4e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_192_emit_[44] = { 0x45, 0x30, 0x45, 0x31, 0x45, 0x32, 0x45, 0x61, 0x45, 0x63, 0x45, 0x65, 0x45, 0x69, 0x45, 0x6f, 0x45, 0x73, 0x45, 0x74, 0x45, 0x20, 0x45, 0x25, 0x45, 0x2d, 0x45, 0x2e, 0x45, 0x2f, 0x45, 0x33, 0x45, 0x34, 0x45, 0x35, 0x45, 0x36, 0x45, 0x37, 0x45, 0x38, 0x45, 0x39}; -const uint8_t HuffDecoderCommon::table11_193_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_193_emit_[91] = { 0x45, 0x3d, 0x45, 0x41, 0x45, 0x5f, 0x45, 0x62, 0x45, 0x64, 0x45, 0x66, 0x45, 0x67, 0x45, 0x68, 0x45, 0x6c, 0x45, 0x6d, 0x45, 0x6e, 0x45, 0x70, 0x45, 0x72, 0x45, 0x75, 0x45, 0x3a, 0x45, 0x42, 0x45, 0x43, 0x45, 0x44, @@ -3059,19 +3097,19 @@ const uint8_t HuffDecoderCommon::table11_193_emit_[91] = { 0x51, 0x45, 0x52, 0x45, 0x53, 0x45, 0x54, 0x45, 0x55, 0x45, 0x56, 0x45, 0x57, 0x45, 0x59, 0x45, 0x6a, 0x45, 0x6b, 0x45, 0x71, 0x45, 0x76, 0x45, 0x77, 0x45, 0x78, 0x45, 0x79, 0x45, 0x7a}; -const uint16_t HuffDecoderCommon::table11_193_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0095, 0x009d, 0x00a5, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_194_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_193_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x094e, 0x09ce, 0x0a4e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_194_emit_[44] = { 0x46, 0x30, 0x46, 0x31, 0x46, 0x32, 0x46, 0x61, 0x46, 0x63, 0x46, 0x65, 0x46, 0x69, 0x46, 0x6f, 0x46, 0x73, 0x46, 0x74, 0x46, 0x20, 0x46, 0x25, 0x46, 0x2d, 0x46, 0x2e, 0x46, 0x2f, 0x46, 0x33, 0x46, 0x34, 0x46, 0x35, 0x46, 0x36, 0x46, 0x37, 0x46, 0x38, 0x46, 0x39}; -const uint8_t HuffDecoderCommon::table11_195_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_195_emit_[91] = { 0x46, 0x3d, 0x46, 0x41, 0x46, 0x5f, 0x46, 0x62, 0x46, 0x64, 0x46, 0x66, 0x46, 0x67, 0x46, 0x68, 0x46, 0x6c, 0x46, 0x6d, 0x46, 0x6e, 0x46, 0x70, 0x46, 0x72, 0x46, 0x75, 0x46, 0x3a, 0x46, 0x42, 0x46, 0x43, 0x46, 0x44, @@ -3080,19 +3118,19 @@ const uint8_t HuffDecoderCommon::table11_195_emit_[91] = { 0x51, 0x46, 0x52, 0x46, 0x53, 0x46, 0x54, 0x46, 0x55, 0x46, 0x56, 0x46, 0x57, 0x46, 0x59, 0x46, 0x6a, 0x46, 0x6b, 0x46, 0x71, 0x46, 0x76, 0x46, 0x77, 0x46, 0x78, 0x46, 0x79, 0x46, 0x7a}; -const uint16_t HuffDecoderCommon::table11_195_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x009d, 0x00a5, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_196_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_195_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x09ce, 0x0a4e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_196_emit_[44] = { 0x47, 0x30, 0x47, 0x31, 0x47, 0x32, 0x47, 0x61, 0x47, 0x63, 0x47, 0x65, 0x47, 0x69, 0x47, 0x6f, 0x47, 0x73, 0x47, 0x74, 0x47, 0x20, 0x47, 0x25, 0x47, 0x2d, 0x47, 0x2e, 0x47, 0x2f, 0x47, 0x33, 0x47, 0x34, 0x47, 0x35, 0x47, 0x36, 0x47, 0x37, 0x47, 0x38, 0x47, 0x39}; -const uint8_t HuffDecoderCommon::table11_197_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_197_emit_[91] = { 0x47, 0x3d, 0x47, 0x41, 0x47, 0x5f, 0x47, 0x62, 0x47, 0x64, 0x47, 0x66, 0x47, 0x67, 0x47, 0x68, 0x47, 0x6c, 0x47, 0x6d, 0x47, 0x6e, 0x47, 0x70, 0x47, 0x72, 0x47, 0x75, 0x47, 0x3a, 0x47, 0x42, 0x47, 0x43, 0x47, 0x44, @@ -3101,19 +3139,19 @@ const uint8_t HuffDecoderCommon::table11_197_emit_[91] = { 0x51, 0x47, 0x52, 0x47, 0x53, 0x47, 0x54, 0x47, 0x55, 0x47, 0x56, 0x47, 0x57, 0x47, 0x59, 0x47, 0x6a, 0x47, 0x6b, 0x47, 0x71, 0x47, 0x76, 0x47, 0x77, 0x47, 0x78, 0x47, 0x79, 0x47, 0x7a}; -const uint16_t HuffDecoderCommon::table11_197_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a5, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_198_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_197_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a4e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_198_emit_[44] = { 0x48, 0x30, 0x48, 0x31, 0x48, 0x32, 0x48, 0x61, 0x48, 0x63, 0x48, 0x65, 0x48, 0x69, 0x48, 0x6f, 0x48, 0x73, 0x48, 0x74, 0x48, 0x20, 0x48, 0x25, 0x48, 0x2d, 0x48, 0x2e, 0x48, 0x2f, 0x48, 0x33, 0x48, 0x34, 0x48, 0x35, 0x48, 0x36, 0x48, 0x37, 0x48, 0x38, 0x48, 0x39}; -const uint8_t HuffDecoderCommon::table11_199_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_199_emit_[91] = { 0x48, 0x3d, 0x48, 0x41, 0x48, 0x5f, 0x48, 0x62, 0x48, 0x64, 0x48, 0x66, 0x48, 0x67, 0x48, 0x68, 0x48, 0x6c, 0x48, 0x6d, 0x48, 0x6e, 0x48, 0x70, 0x48, 0x72, 0x48, 0x75, 0x48, 0x3a, 0x48, 0x42, 0x48, 0x43, 0x48, 0x44, @@ -3122,19 +3160,19 @@ const uint8_t HuffDecoderCommon::table11_199_emit_[91] = { 0x51, 0x48, 0x52, 0x48, 0x53, 0x48, 0x54, 0x48, 0x55, 0x48, 0x56, 0x48, 0x57, 0x48, 0x59, 0x48, 0x6a, 0x48, 0x6b, 0x48, 0x71, 0x48, 0x76, 0x48, 0x77, 0x48, 0x78, 0x48, 0x79, 0x48, 0x7a}; -const uint16_t HuffDecoderCommon::table11_199_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00ad, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_200_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_199_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0ace, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_200_emit_[44] = { 0x49, 0x30, 0x49, 0x31, 0x49, 0x32, 0x49, 0x61, 0x49, 0x63, 0x49, 0x65, 0x49, 0x69, 0x49, 0x6f, 0x49, 0x73, 0x49, 0x74, 0x49, 0x20, 0x49, 0x25, 0x49, 0x2d, 0x49, 0x2e, 0x49, 0x2f, 0x49, 0x33, 0x49, 0x34, 0x49, 0x35, 0x49, 0x36, 0x49, 0x37, 0x49, 0x38, 0x49, 0x39}; -const uint8_t HuffDecoderCommon::table11_201_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_201_emit_[91] = { 0x49, 0x3d, 0x49, 0x41, 0x49, 0x5f, 0x49, 0x62, 0x49, 0x64, 0x49, 0x66, 0x49, 0x67, 0x49, 0x68, 0x49, 0x6c, 0x49, 0x6d, 0x49, 0x6e, 0x49, 0x70, 0x49, 0x72, 0x49, 0x75, 0x49, 0x3a, 0x49, 0x42, 0x49, 0x43, 0x49, 0x44, @@ -3143,19 +3181,19 @@ const uint8_t HuffDecoderCommon::table11_201_emit_[91] = { 0x51, 0x49, 0x52, 0x49, 0x53, 0x49, 0x54, 0x49, 0x55, 0x49, 0x56, 0x49, 0x57, 0x49, 0x59, 0x49, 0x6a, 0x49, 0x6b, 0x49, 0x71, 0x49, 0x76, 0x49, 0x77, 0x49, 0x78, 0x49, 0x79, 0x49, 0x7a}; -const uint16_t HuffDecoderCommon::table11_201_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b5, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_202_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_201_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b4e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_202_emit_[44] = { 0x4a, 0x30, 0x4a, 0x31, 0x4a, 0x32, 0x4a, 0x61, 0x4a, 0x63, 0x4a, 0x65, 0x4a, 0x69, 0x4a, 0x6f, 0x4a, 0x73, 0x4a, 0x74, 0x4a, 0x20, 0x4a, 0x25, 0x4a, 0x2d, 0x4a, 0x2e, 0x4a, 0x2f, 0x4a, 0x33, 0x4a, 0x34, 0x4a, 0x35, 0x4a, 0x36, 0x4a, 0x37, 0x4a, 0x38, 0x4a, 0x39}; -const uint8_t HuffDecoderCommon::table11_203_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_203_emit_[91] = { 0x4a, 0x3d, 0x4a, 0x41, 0x4a, 0x5f, 0x4a, 0x62, 0x4a, 0x64, 0x4a, 0x66, 0x4a, 0x67, 0x4a, 0x68, 0x4a, 0x6c, 0x4a, 0x6d, 0x4a, 0x6e, 0x4a, 0x70, 0x4a, 0x72, 0x4a, 0x75, 0x4a, 0x3a, 0x4a, 0x42, 0x4a, 0x43, 0x4a, 0x44, @@ -3164,19 +3202,19 @@ const uint8_t HuffDecoderCommon::table11_203_emit_[91] = { 0x51, 0x4a, 0x52, 0x4a, 0x53, 0x4a, 0x54, 0x4a, 0x55, 0x4a, 0x56, 0x4a, 0x57, 0x4a, 0x59, 0x4a, 0x6a, 0x4a, 0x6b, 0x4a, 0x71, 0x4a, 0x76, 0x4a, 0x77, 0x4a, 0x78, 0x4a, 0x79, 0x4a, 0x7a}; -const uint16_t HuffDecoderCommon::table11_203_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00bd, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_204_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_203_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0bce, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_204_emit_[44] = { 0x4b, 0x30, 0x4b, 0x31, 0x4b, 0x32, 0x4b, 0x61, 0x4b, 0x63, 0x4b, 0x65, 0x4b, 0x69, 0x4b, 0x6f, 0x4b, 0x73, 0x4b, 0x74, 0x4b, 0x20, 0x4b, 0x25, 0x4b, 0x2d, 0x4b, 0x2e, 0x4b, 0x2f, 0x4b, 0x33, 0x4b, 0x34, 0x4b, 0x35, 0x4b, 0x36, 0x4b, 0x37, 0x4b, 0x38, 0x4b, 0x39}; -const uint8_t HuffDecoderCommon::table11_205_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_205_emit_[91] = { 0x4b, 0x3d, 0x4b, 0x41, 0x4b, 0x5f, 0x4b, 0x62, 0x4b, 0x64, 0x4b, 0x66, 0x4b, 0x67, 0x4b, 0x68, 0x4b, 0x6c, 0x4b, 0x6d, 0x4b, 0x6e, 0x4b, 0x70, 0x4b, 0x72, 0x4b, 0x75, 0x4b, 0x3a, 0x4b, 0x42, 0x4b, 0x43, 0x4b, 0x44, @@ -3185,19 +3223,19 @@ const uint8_t HuffDecoderCommon::table11_205_emit_[91] = { 0x51, 0x4b, 0x52, 0x4b, 0x53, 0x4b, 0x54, 0x4b, 0x55, 0x4b, 0x56, 0x4b, 0x57, 0x4b, 0x59, 0x4b, 0x6a, 0x4b, 0x6b, 0x4b, 0x71, 0x4b, 0x76, 0x4b, 0x77, 0x4b, 0x78, 0x4b, 0x79, 0x4b, 0x7a}; -const uint16_t HuffDecoderCommon::table11_205_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c5, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_206_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_205_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c4e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_206_emit_[44] = { 0x4c, 0x30, 0x4c, 0x31, 0x4c, 0x32, 0x4c, 0x61, 0x4c, 0x63, 0x4c, 0x65, 0x4c, 0x69, 0x4c, 0x6f, 0x4c, 0x73, 0x4c, 0x74, 0x4c, 0x20, 0x4c, 0x25, 0x4c, 0x2d, 0x4c, 0x2e, 0x4c, 0x2f, 0x4c, 0x33, 0x4c, 0x34, 0x4c, 0x35, 0x4c, 0x36, 0x4c, 0x37, 0x4c, 0x38, 0x4c, 0x39}; -const uint8_t HuffDecoderCommon::table11_207_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_207_emit_[91] = { 0x4c, 0x3d, 0x4c, 0x41, 0x4c, 0x5f, 0x4c, 0x62, 0x4c, 0x64, 0x4c, 0x66, 0x4c, 0x67, 0x4c, 0x68, 0x4c, 0x6c, 0x4c, 0x6d, 0x4c, 0x6e, 0x4c, 0x70, 0x4c, 0x72, 0x4c, 0x75, 0x4c, 0x3a, 0x4c, 0x42, 0x4c, 0x43, 0x4c, 0x44, @@ -3206,19 +3244,19 @@ const uint8_t HuffDecoderCommon::table11_207_emit_[91] = { 0x51, 0x4c, 0x52, 0x4c, 0x53, 0x4c, 0x54, 0x4c, 0x55, 0x4c, 0x56, 0x4c, 0x57, 0x4c, 0x59, 0x4c, 0x6a, 0x4c, 0x6b, 0x4c, 0x71, 0x4c, 0x76, 0x4c, 0x77, 0x4c, 0x78, 0x4c, 0x79, 0x4c, 0x7a}; -const uint16_t HuffDecoderCommon::table11_207_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00cd, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_208_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_207_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0cce, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_208_emit_[44] = { 0x4d, 0x30, 0x4d, 0x31, 0x4d, 0x32, 0x4d, 0x61, 0x4d, 0x63, 0x4d, 0x65, 0x4d, 0x69, 0x4d, 0x6f, 0x4d, 0x73, 0x4d, 0x74, 0x4d, 0x20, 0x4d, 0x25, 0x4d, 0x2d, 0x4d, 0x2e, 0x4d, 0x2f, 0x4d, 0x33, 0x4d, 0x34, 0x4d, 0x35, 0x4d, 0x36, 0x4d, 0x37, 0x4d, 0x38, 0x4d, 0x39}; -const uint8_t HuffDecoderCommon::table11_209_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_209_emit_[91] = { 0x4d, 0x3d, 0x4d, 0x41, 0x4d, 0x5f, 0x4d, 0x62, 0x4d, 0x64, 0x4d, 0x66, 0x4d, 0x67, 0x4d, 0x68, 0x4d, 0x6c, 0x4d, 0x6d, 0x4d, 0x6e, 0x4d, 0x70, 0x4d, 0x72, 0x4d, 0x75, 0x4d, 0x3a, 0x4d, 0x42, 0x4d, 0x43, 0x4d, 0x44, @@ -3227,19 +3265,19 @@ const uint8_t HuffDecoderCommon::table11_209_emit_[91] = { 0x51, 0x4d, 0x52, 0x4d, 0x53, 0x4d, 0x54, 0x4d, 0x55, 0x4d, 0x56, 0x4d, 0x57, 0x4d, 0x59, 0x4d, 0x6a, 0x4d, 0x6b, 0x4d, 0x71, 0x4d, 0x76, 0x4d, 0x77, 0x4d, 0x78, 0x4d, 0x79, 0x4d, 0x7a}; -const uint16_t HuffDecoderCommon::table11_209_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d5, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_210_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_209_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d4e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_210_emit_[44] = { 0x4e, 0x30, 0x4e, 0x31, 0x4e, 0x32, 0x4e, 0x61, 0x4e, 0x63, 0x4e, 0x65, 0x4e, 0x69, 0x4e, 0x6f, 0x4e, 0x73, 0x4e, 0x74, 0x4e, 0x20, 0x4e, 0x25, 0x4e, 0x2d, 0x4e, 0x2e, 0x4e, 0x2f, 0x4e, 0x33, 0x4e, 0x34, 0x4e, 0x35, 0x4e, 0x36, 0x4e, 0x37, 0x4e, 0x38, 0x4e, 0x39}; -const uint8_t HuffDecoderCommon::table11_211_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_211_emit_[91] = { 0x4e, 0x3d, 0x4e, 0x41, 0x4e, 0x5f, 0x4e, 0x62, 0x4e, 0x64, 0x4e, 0x66, 0x4e, 0x67, 0x4e, 0x68, 0x4e, 0x6c, 0x4e, 0x6d, 0x4e, 0x6e, 0x4e, 0x70, 0x4e, 0x72, 0x4e, 0x75, 0x4e, 0x3a, 0x4e, 0x42, 0x4e, 0x43, 0x4e, 0x44, @@ -3248,19 +3286,19 @@ const uint8_t HuffDecoderCommon::table11_211_emit_[91] = { 0x51, 0x4e, 0x52, 0x4e, 0x53, 0x4e, 0x54, 0x4e, 0x55, 0x4e, 0x56, 0x4e, 0x57, 0x4e, 0x59, 0x4e, 0x6a, 0x4e, 0x6b, 0x4e, 0x71, 0x4e, 0x76, 0x4e, 0x77, 0x4e, 0x78, 0x4e, 0x79, 0x4e, 0x7a}; -const uint16_t HuffDecoderCommon::table11_211_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00dd, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_212_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_211_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0dce, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_212_emit_[44] = { 0x4f, 0x30, 0x4f, 0x31, 0x4f, 0x32, 0x4f, 0x61, 0x4f, 0x63, 0x4f, 0x65, 0x4f, 0x69, 0x4f, 0x6f, 0x4f, 0x73, 0x4f, 0x74, 0x4f, 0x20, 0x4f, 0x25, 0x4f, 0x2d, 0x4f, 0x2e, 0x4f, 0x2f, 0x4f, 0x33, 0x4f, 0x34, 0x4f, 0x35, 0x4f, 0x36, 0x4f, 0x37, 0x4f, 0x38, 0x4f, 0x39}; -const uint8_t HuffDecoderCommon::table11_213_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_213_emit_[91] = { 0x4f, 0x3d, 0x4f, 0x41, 0x4f, 0x5f, 0x4f, 0x62, 0x4f, 0x64, 0x4f, 0x66, 0x4f, 0x67, 0x4f, 0x68, 0x4f, 0x6c, 0x4f, 0x6d, 0x4f, 0x6e, 0x4f, 0x70, 0x4f, 0x72, 0x4f, 0x75, 0x4f, 0x3a, 0x4f, 0x42, 0x4f, 0x43, 0x4f, 0x44, @@ -3269,19 +3307,19 @@ const uint8_t HuffDecoderCommon::table11_213_emit_[91] = { 0x51, 0x4f, 0x52, 0x4f, 0x53, 0x4f, 0x54, 0x4f, 0x55, 0x4f, 0x56, 0x4f, 0x57, 0x4f, 0x59, 0x4f, 0x6a, 0x4f, 0x6b, 0x4f, 0x71, 0x4f, 0x76, 0x4f, 0x77, 0x4f, 0x78, 0x4f, 0x79, 0x4f, 0x7a}; -const uint16_t HuffDecoderCommon::table11_213_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e5, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_214_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_213_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e4e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_214_emit_[44] = { 0x50, 0x30, 0x50, 0x31, 0x50, 0x32, 0x50, 0x61, 0x50, 0x63, 0x50, 0x65, 0x50, 0x69, 0x50, 0x6f, 0x50, 0x73, 0x50, 0x74, 0x50, 0x20, 0x50, 0x25, 0x50, 0x2d, 0x50, 0x2e, 0x50, 0x2f, 0x50, 0x33, 0x50, 0x34, 0x50, 0x35, 0x50, 0x36, 0x50, 0x37, 0x50, 0x38, 0x50, 0x39}; -const uint8_t HuffDecoderCommon::table11_215_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_215_emit_[91] = { 0x50, 0x3d, 0x50, 0x41, 0x50, 0x5f, 0x50, 0x62, 0x50, 0x64, 0x50, 0x66, 0x50, 0x67, 0x50, 0x68, 0x50, 0x6c, 0x50, 0x6d, 0x50, 0x6e, 0x50, 0x70, 0x50, 0x72, 0x50, 0x75, 0x50, 0x3a, 0x50, 0x42, 0x50, 0x43, 0x50, 0x44, @@ -3290,19 +3328,19 @@ const uint8_t HuffDecoderCommon::table11_215_emit_[91] = { 0x51, 0x50, 0x52, 0x50, 0x53, 0x50, 0x54, 0x50, 0x55, 0x50, 0x56, 0x50, 0x57, 0x50, 0x59, 0x50, 0x6a, 0x50, 0x6b, 0x50, 0x71, 0x50, 0x76, 0x50, 0x77, 0x50, 0x78, 0x50, 0x79, 0x50, 0x7a}; -const uint16_t HuffDecoderCommon::table11_215_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00ed, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_216_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_215_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0ece, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_216_emit_[44] = { 0x51, 0x30, 0x51, 0x31, 0x51, 0x32, 0x51, 0x61, 0x51, 0x63, 0x51, 0x65, 0x51, 0x69, 0x51, 0x6f, 0x51, 0x73, 0x51, 0x74, 0x51, 0x20, 0x51, 0x25, 0x51, 0x2d, 0x51, 0x2e, 0x51, 0x2f, 0x51, 0x33, 0x51, 0x34, 0x51, 0x35, 0x51, 0x36, 0x51, 0x37, 0x51, 0x38, 0x51, 0x39}; -const uint8_t HuffDecoderCommon::table11_217_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_217_emit_[91] = { 0x51, 0x3d, 0x51, 0x41, 0x51, 0x5f, 0x51, 0x62, 0x51, 0x64, 0x51, 0x66, 0x51, 0x67, 0x51, 0x68, 0x51, 0x6c, 0x51, 0x6d, 0x51, 0x6e, 0x51, 0x70, 0x51, 0x72, 0x51, 0x75, 0x51, 0x3a, 0x51, 0x42, 0x51, 0x43, 0x51, 0x44, @@ -3311,19 +3349,19 @@ const uint8_t HuffDecoderCommon::table11_217_emit_[91] = { 0x51, 0x51, 0x52, 0x51, 0x53, 0x51, 0x54, 0x51, 0x55, 0x51, 0x56, 0x51, 0x57, 0x51, 0x59, 0x51, 0x6a, 0x51, 0x6b, 0x51, 0x71, 0x51, 0x76, 0x51, 0x77, 0x51, 0x78, 0x51, 0x79, 0x51, 0x7a}; -const uint16_t HuffDecoderCommon::table11_217_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f5, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_218_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_217_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f4e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_218_emit_[44] = { 0x52, 0x30, 0x52, 0x31, 0x52, 0x32, 0x52, 0x61, 0x52, 0x63, 0x52, 0x65, 0x52, 0x69, 0x52, 0x6f, 0x52, 0x73, 0x52, 0x74, 0x52, 0x20, 0x52, 0x25, 0x52, 0x2d, 0x52, 0x2e, 0x52, 0x2f, 0x52, 0x33, 0x52, 0x34, 0x52, 0x35, 0x52, 0x36, 0x52, 0x37, 0x52, 0x38, 0x52, 0x39}; -const uint8_t HuffDecoderCommon::table11_219_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_219_emit_[91] = { 0x52, 0x3d, 0x52, 0x41, 0x52, 0x5f, 0x52, 0x62, 0x52, 0x64, 0x52, 0x66, 0x52, 0x67, 0x52, 0x68, 0x52, 0x6c, 0x52, 0x6d, 0x52, 0x6e, 0x52, 0x70, 0x52, 0x72, 0x52, 0x75, 0x52, 0x3a, 0x52, 0x42, 0x52, 0x43, 0x52, 0x44, @@ -3332,19 +3370,19 @@ const uint8_t HuffDecoderCommon::table11_219_emit_[91] = { 0x52, 0x51, 0x52, 0x52, 0x53, 0x52, 0x54, 0x52, 0x55, 0x52, 0x56, 0x52, 0x57, 0x52, 0x59, 0x52, 0x6a, 0x52, 0x6b, 0x52, 0x71, 0x52, 0x76, 0x52, 0x77, 0x52, 0x78, 0x52, 0x79, 0x52, 0x7a}; -const uint16_t HuffDecoderCommon::table11_219_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x00fd, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_220_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_219_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x0fce, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_220_emit_[44] = { 0x53, 0x30, 0x53, 0x31, 0x53, 0x32, 0x53, 0x61, 0x53, 0x63, 0x53, 0x65, 0x53, 0x69, 0x53, 0x6f, 0x53, 0x73, 0x53, 0x74, 0x53, 0x20, 0x53, 0x25, 0x53, 0x2d, 0x53, 0x2e, 0x53, 0x2f, 0x53, 0x33, 0x53, 0x34, 0x53, 0x35, 0x53, 0x36, 0x53, 0x37, 0x53, 0x38, 0x53, 0x39}; -const uint8_t HuffDecoderCommon::table11_221_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_221_emit_[91] = { 0x53, 0x3d, 0x53, 0x41, 0x53, 0x5f, 0x53, 0x62, 0x53, 0x64, 0x53, 0x66, 0x53, 0x67, 0x53, 0x68, 0x53, 0x6c, 0x53, 0x6d, 0x53, 0x6e, 0x53, 0x70, 0x53, 0x72, 0x53, 0x75, 0x53, 0x3a, 0x53, 0x42, 0x53, 0x43, 0x53, 0x44, @@ -3353,19 +3391,19 @@ const uint8_t HuffDecoderCommon::table11_221_emit_[91] = { 0x53, 0x51, 0x53, 0x52, 0x53, 0x53, 0x54, 0x53, 0x55, 0x53, 0x56, 0x53, 0x57, 0x53, 0x59, 0x53, 0x6a, 0x53, 0x6b, 0x53, 0x71, 0x53, 0x76, 0x53, 0x77, 0x53, 0x78, 0x53, 0x79, 0x53, 0x7a}; -const uint16_t HuffDecoderCommon::table11_221_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0105, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_222_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_221_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x104e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_222_emit_[44] = { 0x54, 0x30, 0x54, 0x31, 0x54, 0x32, 0x54, 0x61, 0x54, 0x63, 0x54, 0x65, 0x54, 0x69, 0x54, 0x6f, 0x54, 0x73, 0x54, 0x74, 0x54, 0x20, 0x54, 0x25, 0x54, 0x2d, 0x54, 0x2e, 0x54, 0x2f, 0x54, 0x33, 0x54, 0x34, 0x54, 0x35, 0x54, 0x36, 0x54, 0x37, 0x54, 0x38, 0x54, 0x39}; -const uint8_t HuffDecoderCommon::table11_223_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_223_emit_[91] = { 0x54, 0x3d, 0x54, 0x41, 0x54, 0x5f, 0x54, 0x62, 0x54, 0x64, 0x54, 0x66, 0x54, 0x67, 0x54, 0x68, 0x54, 0x6c, 0x54, 0x6d, 0x54, 0x6e, 0x54, 0x70, 0x54, 0x72, 0x54, 0x75, 0x54, 0x3a, 0x54, 0x42, 0x54, 0x43, 0x54, 0x44, @@ -3374,19 +3412,19 @@ const uint8_t HuffDecoderCommon::table11_223_emit_[91] = { 0x54, 0x51, 0x54, 0x52, 0x54, 0x53, 0x54, 0x54, 0x55, 0x54, 0x56, 0x54, 0x57, 0x54, 0x59, 0x54, 0x6a, 0x54, 0x6b, 0x54, 0x71, 0x54, 0x76, 0x54, 0x77, 0x54, 0x78, 0x54, 0x79, 0x54, 0x7a}; -const uint16_t HuffDecoderCommon::table11_223_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x010d, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_224_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_223_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x10ce, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_224_emit_[44] = { 0x55, 0x30, 0x55, 0x31, 0x55, 0x32, 0x55, 0x61, 0x55, 0x63, 0x55, 0x65, 0x55, 0x69, 0x55, 0x6f, 0x55, 0x73, 0x55, 0x74, 0x55, 0x20, 0x55, 0x25, 0x55, 0x2d, 0x55, 0x2e, 0x55, 0x2f, 0x55, 0x33, 0x55, 0x34, 0x55, 0x35, 0x55, 0x36, 0x55, 0x37, 0x55, 0x38, 0x55, 0x39}; -const uint8_t HuffDecoderCommon::table11_225_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_225_emit_[91] = { 0x55, 0x3d, 0x55, 0x41, 0x55, 0x5f, 0x55, 0x62, 0x55, 0x64, 0x55, 0x66, 0x55, 0x67, 0x55, 0x68, 0x55, 0x6c, 0x55, 0x6d, 0x55, 0x6e, 0x55, 0x70, 0x55, 0x72, 0x55, 0x75, 0x55, 0x3a, 0x55, 0x42, 0x55, 0x43, 0x55, 0x44, @@ -3395,19 +3433,19 @@ const uint8_t HuffDecoderCommon::table11_225_emit_[91] = { 0x55, 0x51, 0x55, 0x52, 0x55, 0x53, 0x55, 0x54, 0x55, 0x55, 0x56, 0x55, 0x57, 0x55, 0x59, 0x55, 0x6a, 0x55, 0x6b, 0x55, 0x71, 0x55, 0x76, 0x55, 0x77, 0x55, 0x78, 0x55, 0x79, 0x55, 0x7a}; -const uint16_t HuffDecoderCommon::table11_225_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0115, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_226_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_225_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x114e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_226_emit_[44] = { 0x56, 0x30, 0x56, 0x31, 0x56, 0x32, 0x56, 0x61, 0x56, 0x63, 0x56, 0x65, 0x56, 0x69, 0x56, 0x6f, 0x56, 0x73, 0x56, 0x74, 0x56, 0x20, 0x56, 0x25, 0x56, 0x2d, 0x56, 0x2e, 0x56, 0x2f, 0x56, 0x33, 0x56, 0x34, 0x56, 0x35, 0x56, 0x36, 0x56, 0x37, 0x56, 0x38, 0x56, 0x39}; -const uint8_t HuffDecoderCommon::table11_227_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_227_emit_[91] = { 0x56, 0x3d, 0x56, 0x41, 0x56, 0x5f, 0x56, 0x62, 0x56, 0x64, 0x56, 0x66, 0x56, 0x67, 0x56, 0x68, 0x56, 0x6c, 0x56, 0x6d, 0x56, 0x6e, 0x56, 0x70, 0x56, 0x72, 0x56, 0x75, 0x56, 0x3a, 0x56, 0x42, 0x56, 0x43, 0x56, 0x44, @@ -3416,19 +3454,19 @@ const uint8_t HuffDecoderCommon::table11_227_emit_[91] = { 0x56, 0x51, 0x56, 0x52, 0x56, 0x53, 0x56, 0x54, 0x56, 0x55, 0x56, 0x56, 0x57, 0x56, 0x59, 0x56, 0x6a, 0x56, 0x6b, 0x56, 0x71, 0x56, 0x76, 0x56, 0x77, 0x56, 0x78, 0x56, 0x79, 0x56, 0x7a}; -const uint16_t HuffDecoderCommon::table11_227_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x011d, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_228_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_227_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x11ce, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_228_emit_[44] = { 0x57, 0x30, 0x57, 0x31, 0x57, 0x32, 0x57, 0x61, 0x57, 0x63, 0x57, 0x65, 0x57, 0x69, 0x57, 0x6f, 0x57, 0x73, 0x57, 0x74, 0x57, 0x20, 0x57, 0x25, 0x57, 0x2d, 0x57, 0x2e, 0x57, 0x2f, 0x57, 0x33, 0x57, 0x34, 0x57, 0x35, 0x57, 0x36, 0x57, 0x37, 0x57, 0x38, 0x57, 0x39}; -const uint8_t HuffDecoderCommon::table11_229_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_229_emit_[91] = { 0x57, 0x3d, 0x57, 0x41, 0x57, 0x5f, 0x57, 0x62, 0x57, 0x64, 0x57, 0x66, 0x57, 0x67, 0x57, 0x68, 0x57, 0x6c, 0x57, 0x6d, 0x57, 0x6e, 0x57, 0x70, 0x57, 0x72, 0x57, 0x75, 0x57, 0x3a, 0x57, 0x42, 0x57, 0x43, 0x57, 0x44, @@ -3437,19 +3475,19 @@ const uint8_t HuffDecoderCommon::table11_229_emit_[91] = { 0x57, 0x51, 0x57, 0x52, 0x57, 0x53, 0x57, 0x54, 0x57, 0x55, 0x57, 0x56, 0x57, 0x57, 0x59, 0x57, 0x6a, 0x57, 0x6b, 0x57, 0x71, 0x57, 0x76, 0x57, 0x77, 0x57, 0x78, 0x57, 0x79, 0x57, 0x7a}; -const uint16_t HuffDecoderCommon::table11_229_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0125, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_230_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_229_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x124e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_230_emit_[44] = { 0x59, 0x30, 0x59, 0x31, 0x59, 0x32, 0x59, 0x61, 0x59, 0x63, 0x59, 0x65, 0x59, 0x69, 0x59, 0x6f, 0x59, 0x73, 0x59, 0x74, 0x59, 0x20, 0x59, 0x25, 0x59, 0x2d, 0x59, 0x2e, 0x59, 0x2f, 0x59, 0x33, 0x59, 0x34, 0x59, 0x35, 0x59, 0x36, 0x59, 0x37, 0x59, 0x38, 0x59, 0x39}; -const uint8_t HuffDecoderCommon::table11_231_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_231_emit_[91] = { 0x59, 0x3d, 0x59, 0x41, 0x59, 0x5f, 0x59, 0x62, 0x59, 0x64, 0x59, 0x66, 0x59, 0x67, 0x59, 0x68, 0x59, 0x6c, 0x59, 0x6d, 0x59, 0x6e, 0x59, 0x70, 0x59, 0x72, 0x59, 0x75, 0x59, 0x3a, 0x59, 0x42, 0x59, 0x43, 0x59, 0x44, @@ -3458,19 +3496,19 @@ const uint8_t HuffDecoderCommon::table11_231_emit_[91] = { 0x59, 0x51, 0x59, 0x52, 0x59, 0x53, 0x59, 0x54, 0x59, 0x55, 0x59, 0x56, 0x59, 0x57, 0x59, 0x59, 0x6a, 0x59, 0x6b, 0x59, 0x71, 0x59, 0x76, 0x59, 0x77, 0x59, 0x78, 0x59, 0x79, 0x59, 0x7a}; -const uint16_t HuffDecoderCommon::table11_231_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x012d, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_232_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_231_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x12ce, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_232_emit_[44] = { 0x6a, 0x30, 0x6a, 0x31, 0x6a, 0x32, 0x6a, 0x61, 0x6a, 0x63, 0x6a, 0x65, 0x6a, 0x69, 0x6a, 0x6f, 0x6a, 0x73, 0x6a, 0x74, 0x6a, 0x20, 0x6a, 0x25, 0x6a, 0x2d, 0x6a, 0x2e, 0x6a, 0x2f, 0x6a, 0x33, 0x6a, 0x34, 0x6a, 0x35, 0x6a, 0x36, 0x6a, 0x37, 0x6a, 0x38, 0x6a, 0x39}; -const uint8_t HuffDecoderCommon::table11_233_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_233_emit_[91] = { 0x6a, 0x3d, 0x6a, 0x41, 0x6a, 0x5f, 0x6a, 0x62, 0x6a, 0x64, 0x6a, 0x66, 0x6a, 0x67, 0x6a, 0x68, 0x6a, 0x6c, 0x6a, 0x6d, 0x6a, 0x6e, 0x6a, 0x70, 0x6a, 0x72, 0x6a, 0x75, 0x6a, 0x3a, 0x6a, 0x42, 0x6a, 0x43, 0x6a, 0x44, @@ -3479,19 +3517,19 @@ const uint8_t HuffDecoderCommon::table11_233_emit_[91] = { 0x6a, 0x51, 0x6a, 0x52, 0x6a, 0x53, 0x6a, 0x54, 0x6a, 0x55, 0x6a, 0x56, 0x6a, 0x57, 0x6a, 0x59, 0x6a, 0x6a, 0x6b, 0x6a, 0x71, 0x6a, 0x76, 0x6a, 0x77, 0x6a, 0x78, 0x6a, 0x79, 0x6a, 0x7a}; -const uint16_t HuffDecoderCommon::table11_233_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x0131, - 0x0135, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_234_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_233_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x134e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_234_emit_[44] = { 0x6b, 0x30, 0x6b, 0x31, 0x6b, 0x32, 0x6b, 0x61, 0x6b, 0x63, 0x6b, 0x65, 0x6b, 0x69, 0x6b, 0x6f, 0x6b, 0x73, 0x6b, 0x74, 0x6b, 0x20, 0x6b, 0x25, 0x6b, 0x2d, 0x6b, 0x2e, 0x6b, 0x2f, 0x6b, 0x33, 0x6b, 0x34, 0x6b, 0x35, 0x6b, 0x36, 0x6b, 0x37, 0x6b, 0x38, 0x6b, 0x39}; -const uint8_t HuffDecoderCommon::table11_235_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_235_emit_[91] = { 0x6b, 0x3d, 0x6b, 0x41, 0x6b, 0x5f, 0x6b, 0x62, 0x6b, 0x64, 0x6b, 0x66, 0x6b, 0x67, 0x6b, 0x68, 0x6b, 0x6c, 0x6b, 0x6d, 0x6b, 0x6e, 0x6b, 0x70, 0x6b, 0x72, 0x6b, 0x75, 0x6b, 0x3a, 0x6b, 0x42, 0x6b, 0x43, 0x6b, 0x44, @@ -3500,19 +3538,19 @@ const uint8_t HuffDecoderCommon::table11_235_emit_[91] = { 0x6b, 0x51, 0x6b, 0x52, 0x6b, 0x53, 0x6b, 0x54, 0x6b, 0x55, 0x6b, 0x56, 0x6b, 0x57, 0x6b, 0x59, 0x6b, 0x6a, 0x6b, 0x6b, 0x71, 0x6b, 0x76, 0x6b, 0x77, 0x6b, 0x78, 0x6b, 0x79, 0x6b, 0x7a}; -const uint16_t HuffDecoderCommon::table11_235_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x0131, - 0x0139, 0x013d, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_236_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_235_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x138e, + 0x13ce, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_236_emit_[44] = { 0x71, 0x30, 0x71, 0x31, 0x71, 0x32, 0x71, 0x61, 0x71, 0x63, 0x71, 0x65, 0x71, 0x69, 0x71, 0x6f, 0x71, 0x73, 0x71, 0x74, 0x71, 0x20, 0x71, 0x25, 0x71, 0x2d, 0x71, 0x2e, 0x71, 0x2f, 0x71, 0x33, 0x71, 0x34, 0x71, 0x35, 0x71, 0x36, 0x71, 0x37, 0x71, 0x38, 0x71, 0x39}; -const uint8_t HuffDecoderCommon::table11_237_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_237_emit_[91] = { 0x71, 0x3d, 0x71, 0x41, 0x71, 0x5f, 0x71, 0x62, 0x71, 0x64, 0x71, 0x66, 0x71, 0x67, 0x71, 0x68, 0x71, 0x6c, 0x71, 0x6d, 0x71, 0x6e, 0x71, 0x70, 0x71, 0x72, 0x71, 0x75, 0x71, 0x3a, 0x71, 0x42, 0x71, 0x43, 0x71, 0x44, @@ -3521,19 +3559,19 @@ const uint8_t HuffDecoderCommon::table11_237_emit_[91] = { 0x71, 0x51, 0x71, 0x52, 0x71, 0x53, 0x71, 0x54, 0x71, 0x55, 0x71, 0x56, 0x71, 0x57, 0x71, 0x59, 0x71, 0x6a, 0x71, 0x6b, 0x71, 0x71, 0x76, 0x71, 0x77, 0x71, 0x78, 0x71, 0x79, 0x71, 0x7a}; -const uint16_t HuffDecoderCommon::table11_237_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x0131, - 0x0139, 0x0141, 0x0145, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_238_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_237_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x138e, + 0x140e, 0x144e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_238_emit_[44] = { 0x76, 0x30, 0x76, 0x31, 0x76, 0x32, 0x76, 0x61, 0x76, 0x63, 0x76, 0x65, 0x76, 0x69, 0x76, 0x6f, 0x76, 0x73, 0x76, 0x74, 0x76, 0x20, 0x76, 0x25, 0x76, 0x2d, 0x76, 0x2e, 0x76, 0x2f, 0x76, 0x33, 0x76, 0x34, 0x76, 0x35, 0x76, 0x36, 0x76, 0x37, 0x76, 0x38, 0x76, 0x39}; -const uint8_t HuffDecoderCommon::table11_239_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_239_emit_[91] = { 0x76, 0x3d, 0x76, 0x41, 0x76, 0x5f, 0x76, 0x62, 0x76, 0x64, 0x76, 0x66, 0x76, 0x67, 0x76, 0x68, 0x76, 0x6c, 0x76, 0x6d, 0x76, 0x6e, 0x76, 0x70, 0x76, 0x72, 0x76, 0x75, 0x76, 0x3a, 0x76, 0x42, 0x76, 0x43, 0x76, 0x44, @@ -3542,19 +3580,19 @@ const uint8_t HuffDecoderCommon::table11_239_emit_[91] = { 0x76, 0x51, 0x76, 0x52, 0x76, 0x53, 0x76, 0x54, 0x76, 0x55, 0x76, 0x56, 0x76, 0x57, 0x76, 0x59, 0x76, 0x6a, 0x76, 0x6b, 0x76, 0x71, 0x76, 0x76, 0x77, 0x76, 0x78, 0x76, 0x79, 0x76, 0x7a}; -const uint16_t HuffDecoderCommon::table11_239_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x0131, - 0x0139, 0x0141, 0x0149, 0x014d, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_240_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_239_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x138e, + 0x140e, 0x148e, 0x14ce, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_240_emit_[44] = { 0x77, 0x30, 0x77, 0x31, 0x77, 0x32, 0x77, 0x61, 0x77, 0x63, 0x77, 0x65, 0x77, 0x69, 0x77, 0x6f, 0x77, 0x73, 0x77, 0x74, 0x77, 0x20, 0x77, 0x25, 0x77, 0x2d, 0x77, 0x2e, 0x77, 0x2f, 0x77, 0x33, 0x77, 0x34, 0x77, 0x35, 0x77, 0x36, 0x77, 0x37, 0x77, 0x38, 0x77, 0x39}; -const uint8_t HuffDecoderCommon::table11_241_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_241_emit_[91] = { 0x77, 0x3d, 0x77, 0x41, 0x77, 0x5f, 0x77, 0x62, 0x77, 0x64, 0x77, 0x66, 0x77, 0x67, 0x77, 0x68, 0x77, 0x6c, 0x77, 0x6d, 0x77, 0x6e, 0x77, 0x70, 0x77, 0x72, 0x77, 0x75, 0x77, 0x3a, 0x77, 0x42, 0x77, 0x43, 0x77, 0x44, @@ -3563,19 +3601,19 @@ const uint8_t HuffDecoderCommon::table11_241_emit_[91] = { 0x77, 0x51, 0x77, 0x52, 0x77, 0x53, 0x77, 0x54, 0x77, 0x55, 0x77, 0x56, 0x77, 0x57, 0x77, 0x59, 0x77, 0x6a, 0x77, 0x6b, 0x77, 0x71, 0x77, 0x76, 0x77, 0x77, 0x78, 0x77, 0x79, 0x77, 0x7a}; -const uint16_t HuffDecoderCommon::table11_241_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x0131, - 0x0139, 0x0141, 0x0149, 0x0151, 0x0155, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_242_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_241_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x138e, + 0x140e, 0x148e, 0x150e, 0x154e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_242_emit_[44] = { 0x78, 0x30, 0x78, 0x31, 0x78, 0x32, 0x78, 0x61, 0x78, 0x63, 0x78, 0x65, 0x78, 0x69, 0x78, 0x6f, 0x78, 0x73, 0x78, 0x74, 0x78, 0x20, 0x78, 0x25, 0x78, 0x2d, 0x78, 0x2e, 0x78, 0x2f, 0x78, 0x33, 0x78, 0x34, 0x78, 0x35, 0x78, 0x36, 0x78, 0x37, 0x78, 0x38, 0x78, 0x39}; -const uint8_t HuffDecoderCommon::table11_243_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_243_emit_[91] = { 0x78, 0x3d, 0x78, 0x41, 0x78, 0x5f, 0x78, 0x62, 0x78, 0x64, 0x78, 0x66, 0x78, 0x67, 0x78, 0x68, 0x78, 0x6c, 0x78, 0x6d, 0x78, 0x6e, 0x78, 0x70, 0x78, 0x72, 0x78, 0x75, 0x78, 0x3a, 0x78, 0x42, 0x78, 0x43, 0x78, 0x44, @@ -3584,19 +3622,19 @@ const uint8_t HuffDecoderCommon::table11_243_emit_[91] = { 0x78, 0x51, 0x78, 0x52, 0x78, 0x53, 0x78, 0x54, 0x78, 0x55, 0x78, 0x56, 0x78, 0x57, 0x78, 0x59, 0x78, 0x6a, 0x78, 0x6b, 0x78, 0x71, 0x78, 0x76, 0x78, 0x77, 0x78, 0x78, 0x79, 0x78, 0x7a}; -const uint16_t HuffDecoderCommon::table11_243_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x0131, - 0x0139, 0x0141, 0x0149, 0x0151, 0x0159, 0x015d, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_244_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_243_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x138e, + 0x140e, 0x148e, 0x150e, 0x158e, 0x15ce, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_244_emit_[44] = { 0x79, 0x30, 0x79, 0x31, 0x79, 0x32, 0x79, 0x61, 0x79, 0x63, 0x79, 0x65, 0x79, 0x69, 0x79, 0x6f, 0x79, 0x73, 0x79, 0x74, 0x79, 0x20, 0x79, 0x25, 0x79, 0x2d, 0x79, 0x2e, 0x79, 0x2f, 0x79, 0x33, 0x79, 0x34, 0x79, 0x35, 0x79, 0x36, 0x79, 0x37, 0x79, 0x38, 0x79, 0x39}; -const uint8_t HuffDecoderCommon::table11_245_emit_[91] = { +const uint8_t HuffDecoderCommon::table1_245_emit_[91] = { 0x79, 0x3d, 0x79, 0x41, 0x79, 0x5f, 0x79, 0x62, 0x79, 0x64, 0x79, 0x66, 0x79, 0x67, 0x79, 0x68, 0x79, 0x6c, 0x79, 0x6d, 0x79, 0x6e, 0x79, 0x70, 0x79, 0x72, 0x79, 0x75, 0x79, 0x3a, 0x79, 0x42, 0x79, 0x43, 0x79, 0x44, @@ -3605,19 +3643,19 @@ const uint8_t HuffDecoderCommon::table11_245_emit_[91] = { 0x79, 0x51, 0x79, 0x52, 0x79, 0x53, 0x79, 0x54, 0x79, 0x55, 0x79, 0x56, 0x79, 0x57, 0x79, 0x59, 0x79, 0x6a, 0x79, 0x6b, 0x79, 0x71, 0x79, 0x76, 0x79, 0x77, 0x79, 0x78, 0x79, 0x79, 0x7a}; -const uint16_t HuffDecoderCommon::table11_245_inner_[48] = { - 0x0000, 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, - 0x0039, 0x0041, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, - 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, 0x00b1, - 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, 0x00f1, - 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0121, 0x0129, 0x0131, - 0x0139, 0x0141, 0x0149, 0x0151, 0x0159, 0x0161, 0x0165, 0x0002}; -const uint8_t HuffDecoderCommon::table11_246_emit_[44] = { +const uint16_t HuffDecoderCommon::table1_245_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x138e, + 0x140e, 0x148e, 0x150e, 0x158e, 0x160e, 0x164e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_246_emit_[44] = { 0x7a, 0x30, 0x7a, 0x31, 0x7a, 0x32, 0x7a, 0x61, 0x7a, 0x63, 0x7a, 0x65, 0x7a, 0x69, 0x7a, 0x6f, 0x7a, 0x73, 0x7a, 0x74, 0x7a, 0x20, 0x7a, 0x25, 0x7a, 0x2d, 0x7a, 0x2e, 0x7a, 0x2f, 0x7a, 0x33, 0x7a, 0x34, 0x7a, 0x35, 0x7a, 0x36, 0x7a, 0x37, 0x7a, 0x38, 0x7a, 0x39}; -const uint8_t HuffDecoderCommon::table11_247_emit_[92] = { +const uint8_t HuffDecoderCommon::table1_247_emit_[92] = { 0x7a, 0x3d, 0x7a, 0x41, 0x7a, 0x5f, 0x7a, 0x62, 0x7a, 0x64, 0x7a, 0x66, 0x7a, 0x67, 0x7a, 0x68, 0x7a, 0x6c, 0x7a, 0x6d, 0x7a, 0x6e, 0x7a, 0x70, 0x7a, 0x72, 0x7a, 0x75, 0x7a, 0x3a, 0x7a, 0x42, 0x7a, 0x43, 0x7a, 0x44, @@ -3626,2505 +3664,80 @@ const uint8_t HuffDecoderCommon::table11_247_emit_[92] = { 0x7a, 0x51, 0x7a, 0x52, 0x7a, 0x53, 0x7a, 0x54, 0x7a, 0x55, 0x7a, 0x56, 0x7a, 0x57, 0x7a, 0x59, 0x7a, 0x6a, 0x7a, 0x6b, 0x7a, 0x71, 0x7a, 0x76, 0x7a, 0x77, 0x7a, 0x78, 0x7a, 0x79, 0x7a, 0x7a}; -const uint8_t HuffDecoderCommon::table11_248_emit_[72] = { +const uint16_t HuffDecoderCommon::table1_247_inner_[47] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050d, 0x058d, 0x060d, 0x068d, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x120e, 0x128e, 0x130e, 0x138e, + 0x140e, 0x148e, 0x150e, 0x158e, 0x160e, 0x168e, 0x0017}; +const uint8_t HuffDecoderCommon::table1_248_emit_[72] = { 0x26, 0x30, 0x26, 0x31, 0x26, 0x32, 0x26, 0x61, 0x26, 0x63, 0x26, 0x65, 0x26, 0x69, 0x26, 0x6f, 0x26, 0x73, 0x26, 0x74, 0x26, 0x20, 0x26, 0x25, 0x26, 0x2d, 0x26, 0x2e, 0x26, 0x2f, 0x26, 0x33, 0x26, 0x34, 0x26, 0x35, 0x26, 0x36, 0x26, 0x37, 0x26, 0x38, 0x26, 0x39, 0x26, 0x3d, 0x26, 0x41, 0x26, 0x5f, 0x26, 0x62, 0x26, 0x64, 0x26, 0x66, 0x26, 0x67, 0x26, 0x68, 0x26, 0x6c, 0x26, 0x6d, 0x26, 0x6e, 0x26, 0x70, 0x26, 0x72, 0x26, 0x75}; -const uint8_t HuffDecoderCommon::table11_249_emit_[72] = { +const uint16_t HuffDecoderCommon::table1_248_inner_[37] = { + 0x000d, 0x008d, 0x010d, 0x018d, 0x020d, 0x028d, 0x030d, 0x038d, + 0x040d, 0x048d, 0x050e, 0x058e, 0x060e, 0x068e, 0x070e, 0x078e, + 0x080e, 0x088e, 0x090e, 0x098e, 0x0a0e, 0x0a8e, 0x0b0e, 0x0b8e, + 0x0c0e, 0x0c8e, 0x0d0e, 0x0d8e, 0x0e0e, 0x0e8e, 0x0f0e, 0x0f8e, + 0x100e, 0x108e, 0x110e, 0x118e, 0x0018}; +const uint8_t HuffDecoderCommon::table1_248_outer_[64] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36}; +const uint8_t HuffDecoderCommon::table1_249_emit_[72] = { 0x2a, 0x30, 0x2a, 0x31, 0x2a, 0x32, 0x2a, 0x61, 0x2a, 0x63, 0x2a, 0x65, 0x2a, 0x69, 0x2a, 0x6f, 0x2a, 0x73, 0x2a, 0x74, 0x2a, 0x20, 0x2a, 0x25, 0x2a, 0x2d, 0x2a, 0x2e, 0x2a, 0x2f, 0x2a, 0x33, 0x2a, 0x34, 0x2a, 0x35, 0x2a, 0x36, 0x2a, 0x37, 0x2a, 0x38, 0x2a, 0x39, 0x2a, 0x3d, 0x2a, 0x41, 0x2a, 0x5f, 0x2a, 0x62, 0x2a, 0x64, 0x2a, 0x66, 0x2a, 0x67, 0x2a, 0x68, 0x2a, 0x6c, 0x2a, 0x6d, 0x2a, 0x6e, 0x2a, 0x70, 0x2a, 0x72, 0x2a, 0x75}; -const uint8_t HuffDecoderCommon::table11_250_emit_[72] = { +const uint8_t HuffDecoderCommon::table1_250_emit_[72] = { 0x2c, 0x30, 0x2c, 0x31, 0x2c, 0x32, 0x2c, 0x61, 0x2c, 0x63, 0x2c, 0x65, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x73, 0x2c, 0x74, 0x2c, 0x20, 0x2c, 0x25, 0x2c, 0x2d, 0x2c, 0x2e, 0x2c, 0x2f, 0x2c, 0x33, 0x2c, 0x34, 0x2c, 0x35, 0x2c, 0x36, 0x2c, 0x37, 0x2c, 0x38, 0x2c, 0x39, 0x2c, 0x3d, 0x2c, 0x41, 0x2c, 0x5f, 0x2c, 0x62, 0x2c, 0x64, 0x2c, 0x66, 0x2c, 0x67, 0x2c, 0x68, 0x2c, 0x6c, 0x2c, 0x6d, 0x2c, 0x6e, 0x2c, 0x70, 0x2c, 0x72, 0x2c, 0x75}; -const uint8_t HuffDecoderCommon::table11_251_emit_[72] = { +const uint8_t HuffDecoderCommon::table1_251_emit_[72] = { 0x3b, 0x30, 0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x61, 0x3b, 0x63, 0x3b, 0x65, 0x3b, 0x69, 0x3b, 0x6f, 0x3b, 0x73, 0x3b, 0x74, 0x3b, 0x20, 0x3b, 0x25, 0x3b, 0x2d, 0x3b, 0x2e, 0x3b, 0x2f, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x38, 0x3b, 0x39, 0x3b, 0x3d, 0x3b, 0x41, 0x3b, 0x5f, 0x3b, 0x62, 0x3b, 0x64, 0x3b, 0x66, 0x3b, 0x67, 0x3b, 0x68, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x72, 0x3b, 0x75}; -const uint8_t HuffDecoderCommon::table11_252_emit_[72] = { +const uint8_t HuffDecoderCommon::table1_252_emit_[72] = { 0x58, 0x30, 0x58, 0x31, 0x58, 0x32, 0x58, 0x61, 0x58, 0x63, 0x58, 0x65, 0x58, 0x69, 0x58, 0x6f, 0x58, 0x73, 0x58, 0x74, 0x58, 0x20, 0x58, 0x25, 0x58, 0x2d, 0x58, 0x2e, 0x58, 0x2f, 0x58, 0x33, 0x58, 0x34, 0x58, 0x35, 0x58, 0x36, 0x58, 0x37, 0x58, 0x38, 0x58, 0x39, 0x58, 0x3d, 0x58, 0x41, 0x58, 0x5f, 0x58, 0x62, 0x58, 0x64, 0x58, 0x66, 0x58, 0x67, 0x58, 0x68, 0x58, 0x6c, 0x58, 0x6d, 0x58, 0x6e, 0x58, 0x70, 0x58, 0x72, 0x58, 0x75}; -const uint8_t HuffDecoderCommon::table11_253_emit_[72] = { +const uint8_t HuffDecoderCommon::table1_253_emit_[72] = { 0x5a, 0x30, 0x5a, 0x31, 0x5a, 0x32, 0x5a, 0x61, 0x5a, 0x63, 0x5a, 0x65, 0x5a, 0x69, 0x5a, 0x6f, 0x5a, 0x73, 0x5a, 0x74, 0x5a, 0x20, 0x5a, 0x25, 0x5a, 0x2d, 0x5a, 0x2e, 0x5a, 0x2f, 0x5a, 0x33, 0x5a, 0x34, 0x5a, 0x35, 0x5a, 0x36, 0x5a, 0x37, 0x5a, 0x38, 0x5a, 0x39, 0x5a, 0x3d, 0x5a, 0x41, 0x5a, 0x5f, 0x5a, 0x62, 0x5a, 0x64, 0x5a, 0x66, 0x5a, 0x67, 0x5a, 0x68, 0x5a, 0x6c, 0x5a, 0x6d, 0x5a, 0x6e, 0x5a, 0x70, 0x5a, 0x72, 0x5a, 0x75}; -const uint8_t HuffDecoderCommon::table11_254_emit_[4] = {0x21, 0x22, 0x28, - 0x29}; -const uint8_t HuffDecoderCommon::table11_255_emit_[14] = { +const uint8_t HuffDecoderCommon::table1_254_emit_[4] = {0x21, 0x22, 0x28, 0x29}; +const uint16_t HuffDecoderCommon::table1_254_inner_[4] = {0x001a, 0x005a, + 0x009a, 0x00da}; +const uint8_t HuffDecoderCommon::table1_255_emit_[14] = { 0x3f, 0x27, 0x2b, 0x7c, 0x23, 0x3e, 0x00, 0x24, 0x40, 0x5b, 0x5d, 0x7e, 0x5e, 0x7d}; -const uint8_t HuffDecoderCommon::table11_255_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, - 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 13, 14, 0, 15}; -const uint8_t* const HuffDecoderCommon::table11_emit_[256] = { - table11_0_emit_, table11_1_emit_, table11_2_emit_, table11_3_emit_, - table11_4_emit_, table11_5_emit_, table11_6_emit_, table11_7_emit_, - table11_8_emit_, table11_9_emit_, table11_10_emit_, table11_11_emit_, - table11_12_emit_, table11_13_emit_, table11_14_emit_, table11_15_emit_, - table11_16_emit_, table11_17_emit_, table11_18_emit_, table11_19_emit_, - table11_20_emit_, table11_21_emit_, table11_22_emit_, table11_23_emit_, - table11_24_emit_, table11_25_emit_, table11_26_emit_, table11_27_emit_, - table11_28_emit_, table11_29_emit_, table11_30_emit_, table11_31_emit_, - table11_32_emit_, table11_33_emit_, table11_34_emit_, table11_35_emit_, - table11_36_emit_, table11_37_emit_, table11_38_emit_, table11_39_emit_, - table11_40_emit_, table11_41_emit_, table11_42_emit_, table11_43_emit_, - table11_44_emit_, table11_45_emit_, table11_46_emit_, table11_47_emit_, - table11_48_emit_, table11_49_emit_, table11_50_emit_, table11_51_emit_, - table11_52_emit_, table11_53_emit_, table11_54_emit_, table11_55_emit_, - table11_56_emit_, table11_57_emit_, table11_58_emit_, table11_59_emit_, - table11_60_emit_, table11_61_emit_, table11_62_emit_, table11_63_emit_, - table11_64_emit_, table11_65_emit_, table11_66_emit_, table11_67_emit_, - table11_68_emit_, table11_69_emit_, table11_70_emit_, table11_71_emit_, - table11_72_emit_, table11_73_emit_, table11_74_emit_, table11_75_emit_, - table11_76_emit_, table11_77_emit_, table11_78_emit_, table11_79_emit_, - table11_80_emit_, table11_81_emit_, table11_82_emit_, table11_83_emit_, - table11_84_emit_, table11_85_emit_, table11_86_emit_, table11_87_emit_, - table11_88_emit_, table11_89_emit_, table11_90_emit_, table11_91_emit_, - table11_92_emit_, table11_93_emit_, table11_94_emit_, table11_95_emit_, - table11_96_emit_, table11_97_emit_, table11_98_emit_, table11_99_emit_, - table11_100_emit_, table11_101_emit_, table11_102_emit_, table11_103_emit_, - table11_104_emit_, table11_105_emit_, table11_106_emit_, table11_107_emit_, - table11_108_emit_, table11_109_emit_, table11_110_emit_, table11_111_emit_, - table11_112_emit_, table11_113_emit_, table11_114_emit_, table11_115_emit_, - table11_116_emit_, table11_117_emit_, table11_118_emit_, table11_119_emit_, - table11_120_emit_, table11_121_emit_, table11_122_emit_, table11_123_emit_, - table11_124_emit_, table11_125_emit_, table11_126_emit_, table11_127_emit_, - table11_128_emit_, table11_129_emit_, table11_130_emit_, table11_131_emit_, - table11_132_emit_, table11_133_emit_, table11_134_emit_, table11_135_emit_, - table11_136_emit_, table11_137_emit_, table11_138_emit_, table11_139_emit_, - table11_140_emit_, table11_141_emit_, table11_142_emit_, table11_143_emit_, - table11_144_emit_, table11_145_emit_, table11_146_emit_, table11_147_emit_, - table11_148_emit_, table11_149_emit_, table11_150_emit_, table11_151_emit_, - table11_152_emit_, table11_153_emit_, table11_154_emit_, table11_155_emit_, - table11_156_emit_, table11_157_emit_, table11_158_emit_, table11_159_emit_, - table11_160_emit_, table11_161_emit_, table11_162_emit_, table11_163_emit_, - table11_164_emit_, table11_165_emit_, table11_166_emit_, table11_167_emit_, - table11_168_emit_, table11_169_emit_, table11_170_emit_, table11_171_emit_, - table11_172_emit_, table11_173_emit_, table11_174_emit_, table11_175_emit_, - table11_176_emit_, table11_177_emit_, table11_178_emit_, table11_179_emit_, - table11_180_emit_, table11_181_emit_, table11_182_emit_, table11_183_emit_, - table11_184_emit_, table11_185_emit_, table11_186_emit_, table11_187_emit_, - table11_188_emit_, table11_189_emit_, table11_190_emit_, table11_191_emit_, - table11_192_emit_, table11_193_emit_, table11_194_emit_, table11_195_emit_, - table11_196_emit_, table11_197_emit_, table11_198_emit_, table11_199_emit_, - table11_200_emit_, table11_201_emit_, table11_202_emit_, table11_203_emit_, - table11_204_emit_, table11_205_emit_, table11_206_emit_, table11_207_emit_, - table11_208_emit_, table11_209_emit_, table11_210_emit_, table11_211_emit_, - table11_212_emit_, table11_213_emit_, table11_214_emit_, table11_215_emit_, - table11_216_emit_, table11_217_emit_, table11_218_emit_, table11_219_emit_, - table11_220_emit_, table11_221_emit_, table11_222_emit_, table11_223_emit_, - table11_224_emit_, table11_225_emit_, table11_226_emit_, table11_227_emit_, - table11_228_emit_, table11_229_emit_, table11_230_emit_, table11_231_emit_, - table11_232_emit_, table11_233_emit_, table11_234_emit_, table11_235_emit_, - table11_236_emit_, table11_237_emit_, table11_238_emit_, table11_239_emit_, - table11_240_emit_, table11_241_emit_, table11_242_emit_, table11_243_emit_, - table11_244_emit_, table11_245_emit_, table11_246_emit_, table11_247_emit_, - table11_248_emit_, table11_249_emit_, table11_250_emit_, table11_251_emit_, - table11_252_emit_, table11_253_emit_, table11_254_emit_, table11_255_emit_, -}; -const uint16_t* const HuffDecoderCommon::table11_inner_[256] = { - table11_0_inner_, table11_1_inner_, table11_2_inner_, - table10_28_inner_, table10_28_inner_, table11_5_inner_, - table11_6_inner_, table11_7_inner_, table11_8_inner_, - table11_1_inner_, table11_2_inner_, table10_28_inner_, - table10_28_inner_, table11_5_inner_, table11_6_inner_, - table11_7_inner_, table11_16_inner_, table11_1_inner_, - table11_2_inner_, table10_28_inner_, table10_28_inner_, - table11_5_inner_, table11_6_inner_, table11_7_inner_, - table11_1_inner_, table11_1_inner_, table11_2_inner_, - table10_28_inner_, table10_28_inner_, table11_5_inner_, - table11_6_inner_, table11_7_inner_, table11_1_inner_, - table11_0_inner_, table11_2_inner_, table10_28_inner_, - table10_28_inner_, table11_5_inner_, table11_6_inner_, - table11_7_inner_, table11_1_inner_, table11_8_inner_, - table11_2_inner_, table10_28_inner_, table10_28_inner_, - table11_5_inner_, table11_6_inner_, table11_7_inner_, - table11_1_inner_, table11_16_inner_, table11_2_inner_, - table10_28_inner_, table10_28_inner_, table11_5_inner_, - table11_6_inner_, table11_7_inner_, table11_1_inner_, - table11_1_inner_, table11_2_inner_, table10_28_inner_, - table10_28_inner_, table11_5_inner_, table11_6_inner_, - table11_7_inner_, table11_1_inner_, table11_1_inner_, - table11_66_inner_, table10_28_inner_, table10_28_inner_, - table11_5_inner_, table11_6_inner_, table11_7_inner_, - table11_1_inner_, table11_1_inner_, table11_74_inner_, - table10_28_inner_, table10_28_inner_, table11_5_inner_, - table11_6_inner_, table11_7_inner_, table10_28_inner_, - table11_81_inner_, table10_2_inner_, table10_3_inner_, - table10_28_inner_, table11_85_inner_, table10_2_inner_, - table10_3_inner_, table10_28_inner_, table11_89_inner_, - table10_2_inner_, table10_3_inner_, table10_28_inner_, - table11_93_inner_, table10_2_inner_, table10_3_inner_, - table10_28_inner_, table11_97_inner_, table10_2_inner_, - table10_3_inner_, table10_28_inner_, table11_101_inner_, - table10_2_inner_, table10_3_inner_, table10_28_inner_, - table11_105_inner_, table10_2_inner_, table10_3_inner_, - table10_28_inner_, table11_109_inner_, table10_2_inner_, - table10_3_inner_, table10_28_inner_, table11_113_inner_, - table10_2_inner_, table10_3_inner_, table10_28_inner_, - table11_117_inner_, table10_2_inner_, table10_3_inner_, - table10_28_inner_, table11_121_inner_, table10_2_inner_, - table10_3_inner_, table10_28_inner_, table10_1_inner_, - table10_2_inner_, table10_3_inner_, table10_28_inner_, - table10_1_inner_, table11_130_inner_, table10_3_inner_, - table10_28_inner_, table10_1_inner_, table11_134_inner_, - table10_3_inner_, table10_28_inner_, table10_1_inner_, - table11_138_inner_, table10_3_inner_, table10_28_inner_, - table10_1_inner_, table11_142_inner_, table10_3_inner_, - table10_28_inner_, table10_1_inner_, table11_146_inner_, - table10_3_inner_, table10_28_inner_, table10_1_inner_, - table11_150_inner_, table10_3_inner_, table10_28_inner_, - table10_1_inner_, table11_154_inner_, table10_3_inner_, - table10_28_inner_, table10_1_inner_, table11_158_inner_, - table10_3_inner_, table10_28_inner_, table10_1_inner_, - table11_162_inner_, table10_3_inner_, table10_28_inner_, - table10_1_inner_, table11_166_inner_, table10_3_inner_, - table10_28_inner_, table10_1_inner_, table11_170_inner_, - table10_3_inner_, table10_28_inner_, table10_1_inner_, - table11_174_inner_, table10_3_inner_, table10_28_inner_, - table10_1_inner_, table11_178_inner_, table10_3_inner_, - table10_28_inner_, table10_1_inner_, table11_182_inner_, - table10_3_inner_, table10_62_inner_, table11_185_inner_, - table10_62_inner_, table11_187_inner_, table10_62_inner_, - table11_189_inner_, table10_62_inner_, table11_191_inner_, - table10_62_inner_, table11_193_inner_, table10_62_inner_, - table11_195_inner_, table10_62_inner_, table11_197_inner_, - table10_62_inner_, table11_199_inner_, table10_62_inner_, - table11_201_inner_, table10_62_inner_, table11_203_inner_, - table10_62_inner_, table11_205_inner_, table10_62_inner_, - table11_207_inner_, table10_62_inner_, table11_209_inner_, - table10_62_inner_, table11_211_inner_, table10_62_inner_, - table11_213_inner_, table10_62_inner_, table11_215_inner_, - table10_62_inner_, table11_217_inner_, table10_62_inner_, - table11_219_inner_, table10_62_inner_, table11_221_inner_, - table10_62_inner_, table11_223_inner_, table10_62_inner_, - table11_225_inner_, table10_62_inner_, table11_227_inner_, - table10_62_inner_, table11_229_inner_, table10_62_inner_, - table11_231_inner_, table10_62_inner_, table11_233_inner_, - table10_62_inner_, table11_235_inner_, table10_62_inner_, - table11_237_inner_, table10_62_inner_, table11_239_inner_, - table10_62_inner_, table11_241_inner_, table10_62_inner_, - table11_243_inner_, table10_62_inner_, table11_245_inner_, - table10_62_inner_, table10_41_inner_, table10_92_inner_, - table10_92_inner_, table10_92_inner_, table10_92_inner_, - table10_92_inner_, table10_92_inner_, table8_23_inner_, - table8_31_inner_, -}; -const uint8_t* const HuffDecoderCommon::table11_outer_[256] = { - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table8_23_outer_, table8_23_outer_, table11_2_outer_, table10_0_outer_, - table10_0_outer_, table11_5_outer_, table11_6_outer_, table11_7_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_0_outer_, table10_1_outer_, table10_2_outer_, table10_3_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table10_40_outer_, table10_41_outer_, table10_40_outer_, table10_41_outer_, - table8_0_outer_, table8_0_outer_, table8_0_outer_, table8_0_outer_, - table8_0_outer_, table8_0_outer_, table8_23_outer_, table11_255_outer_, -}; -const uint8_t HuffDecoderCommon::table1_0_emit_[55] = { - 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x32, 0x30, 0x30, 0x61, 0x30, - 0x30, 0x63, 0x30, 0x30, 0x65, 0x30, 0x30, 0x69, 0x30, 0x30, 0x6f, - 0x30, 0x30, 0x73, 0x30, 0x30, 0x74, 0x30, 0x31, 0x31, 0x30, 0x31, - 0x32, 0x30, 0x31, 0x61, 0x30, 0x31, 0x63, 0x30, 0x31, 0x65, 0x30, - 0x31, 0x69, 0x30, 0x31, 0x6f, 0x30, 0x31, 0x73, 0x30, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_0_inner_[22] = { - 0x000f, 0x004f, 0x010f, 0x01cf, 0x028f, 0x034f, 0x040f, 0x04cf, - 0x058f, 0x064f, 0x001a, 0x008f, 0x070f, 0x07cf, 0x088f, 0x094f, - 0x0a0f, 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x009a}; -const uint8_t HuffDecoderCommon::table1_0_outer_[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21}; -const uint8_t HuffDecoderCommon::table1_1_emit_[58] = { - 0x30, 0x32, 0x30, 0x32, 0x31, 0x30, 0x32, 0x32, 0x30, 0x32, 0x61, 0x30, - 0x32, 0x63, 0x30, 0x32, 0x65, 0x30, 0x32, 0x69, 0x30, 0x32, 0x6f, 0x30, - 0x32, 0x73, 0x30, 0x32, 0x74, 0x30, 0x61, 0x30, 0x61, 0x31, 0x30, 0x61, - 0x32, 0x30, 0x61, 0x61, 0x30, 0x61, 0x63, 0x30, 0x61, 0x65, 0x30, 0x61, - 0x69, 0x30, 0x61, 0x6f, 0x30, 0x61, 0x73, 0x30, 0x61, 0x74}; -const uint16_t HuffDecoderCommon::table1_1_inner_[22] = { - 0x000f, 0x008f, 0x014f, 0x020f, 0x02cf, 0x038f, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x07cf, 0x088f, 0x094f, 0x0a0f, - 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_2_emit_[58] = { - 0x30, 0x63, 0x30, 0x63, 0x31, 0x30, 0x63, 0x32, 0x30, 0x63, 0x61, 0x30, - 0x63, 0x63, 0x30, 0x63, 0x65, 0x30, 0x63, 0x69, 0x30, 0x63, 0x6f, 0x30, - 0x63, 0x73, 0x30, 0x63, 0x74, 0x30, 0x65, 0x30, 0x65, 0x31, 0x30, 0x65, - 0x32, 0x30, 0x65, 0x61, 0x30, 0x65, 0x63, 0x30, 0x65, 0x65, 0x30, 0x65, - 0x69, 0x30, 0x65, 0x6f, 0x30, 0x65, 0x73, 0x30, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_3_emit_[58] = { - 0x30, 0x69, 0x30, 0x69, 0x31, 0x30, 0x69, 0x32, 0x30, 0x69, 0x61, 0x30, - 0x69, 0x63, 0x30, 0x69, 0x65, 0x30, 0x69, 0x69, 0x30, 0x69, 0x6f, 0x30, - 0x69, 0x73, 0x30, 0x69, 0x74, 0x30, 0x6f, 0x30, 0x6f, 0x31, 0x30, 0x6f, - 0x32, 0x30, 0x6f, 0x61, 0x30, 0x6f, 0x63, 0x30, 0x6f, 0x65, 0x30, 0x6f, - 0x69, 0x30, 0x6f, 0x6f, 0x30, 0x6f, 0x73, 0x30, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_4_emit_[58] = { - 0x30, 0x73, 0x30, 0x73, 0x31, 0x30, 0x73, 0x32, 0x30, 0x73, 0x61, 0x30, - 0x73, 0x63, 0x30, 0x73, 0x65, 0x30, 0x73, 0x69, 0x30, 0x73, 0x6f, 0x30, - 0x73, 0x73, 0x30, 0x73, 0x74, 0x30, 0x74, 0x30, 0x74, 0x31, 0x30, 0x74, - 0x32, 0x30, 0x74, 0x61, 0x30, 0x74, 0x63, 0x30, 0x74, 0x65, 0x30, 0x74, - 0x69, 0x30, 0x74, 0x6f, 0x30, 0x74, 0x73, 0x30, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_5_emit_[8] = {0x30, 0x20, 0x30, 0x25, - 0x30, 0x2d, 0x30, 0x2e}; -const uint16_t HuffDecoderCommon::table1_5_inner_[4] = {0x001b, 0x009b, 0x011b, - 0x019b}; -const uint8_t HuffDecoderCommon::table1_5_outer_[64] = { - 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; -const uint8_t HuffDecoderCommon::table1_6_emit_[8] = {0x30, 0x2f, 0x30, 0x33, - 0x30, 0x34, 0x30, 0x35}; -const uint8_t HuffDecoderCommon::table1_7_emit_[8] = {0x30, 0x36, 0x30, 0x37, - 0x30, 0x38, 0x30, 0x39}; -const uint8_t HuffDecoderCommon::table1_8_emit_[8] = {0x30, 0x3d, 0x30, 0x41, - 0x30, 0x5f, 0x30, 0x62}; -const uint8_t HuffDecoderCommon::table1_9_emit_[8] = {0x30, 0x64, 0x30, 0x66, - 0x30, 0x67, 0x30, 0x68}; -const uint8_t HuffDecoderCommon::table1_10_emit_[8] = {0x30, 0x6c, 0x30, 0x6d, - 0x30, 0x6e, 0x30, 0x70}; -const uint8_t HuffDecoderCommon::table1_11_emit_[12] = { - 0x30, 0x72, 0x30, 0x75, 0x30, 0x3a, 0x30, 0x42, 0x30, 0x43, 0x30, 0x44}; -const uint16_t HuffDecoderCommon::table1_11_inner_[6] = { - 0x001b, 0x009b, 0x011c, 0x019c, 0x021c, 0x029c}; -const uint8_t HuffDecoderCommon::table1_11_outer_[64] = { - 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, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5}; -const uint8_t HuffDecoderCommon::table1_12_emit_[16] = { - 0x30, 0x45, 0x30, 0x46, 0x30, 0x47, 0x30, 0x48, - 0x30, 0x49, 0x30, 0x4a, 0x30, 0x4b, 0x30, 0x4c}; -const uint16_t HuffDecoderCommon::table1_12_inner_[8] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021c, 0x029c, 0x031c, 0x039c}; -const uint8_t HuffDecoderCommon::table1_12_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, - 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7}; -const uint8_t HuffDecoderCommon::table1_13_emit_[16] = { - 0x30, 0x4d, 0x30, 0x4e, 0x30, 0x4f, 0x30, 0x50, - 0x30, 0x51, 0x30, 0x52, 0x30, 0x53, 0x30, 0x54}; -const uint8_t HuffDecoderCommon::table1_14_emit_[16] = { - 0x30, 0x55, 0x30, 0x56, 0x30, 0x57, 0x30, 0x59, - 0x30, 0x6a, 0x30, 0x6b, 0x30, 0x71, 0x30, 0x76}; -const uint8_t HuffDecoderCommon::table1_15_emit_[30] = { - 0x30, 0x77, 0x30, 0x78, 0x30, 0x79, 0x30, 0x7a, 0x30, 0x26, - 0x30, 0x2a, 0x30, 0x2c, 0x30, 0x3b, 0x30, 0x58, 0x30, 0x5a, - 0x30, 0x21, 0x30, 0x22, 0x30, 0x28, 0x30, 0x29, 0x30, 0x3f}; -const uint16_t HuffDecoderCommon::table1_15_inner_[16] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021d, 0x029d, 0x031d, 0x039d, - 0x041d, 0x049d, 0x051f, 0x059f, 0x061f, 0x069f, 0x071f, 0x0025}; -const uint8_t HuffDecoderCommon::table1_15_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, - 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 11, 12, 13, 14, 15, 15, 15}; -const uint8_t HuffDecoderCommon::table1_16_emit_[57] = { - 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x32, 0x31, 0x30, 0x61, 0x31, - 0x30, 0x63, 0x31, 0x30, 0x65, 0x31, 0x30, 0x69, 0x31, 0x30, 0x6f, 0x31, - 0x30, 0x73, 0x31, 0x30, 0x74, 0x31, 0x31, 0x30, 0x31, 0x31, 0x31, 0x32, - 0x31, 0x31, 0x61, 0x31, 0x31, 0x63, 0x31, 0x31, 0x65, 0x31, 0x31, 0x69, - 0x31, 0x31, 0x6f, 0x31, 0x31, 0x73, 0x31, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_16_inner_[22] = { - 0x000f, 0x00cf, 0x014f, 0x020f, 0x02cf, 0x038f, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x084f, 0x090f, 0x09cf, - 0x0a8f, 0x0b4f, 0x0c0f, 0x0ccf, 0x0d8f, 0x075a}; -const uint8_t HuffDecoderCommon::table1_17_emit_[58] = { - 0x31, 0x32, 0x30, 0x31, 0x32, 0x31, 0x32, 0x32, 0x31, 0x32, 0x61, 0x31, - 0x32, 0x63, 0x31, 0x32, 0x65, 0x31, 0x32, 0x69, 0x31, 0x32, 0x6f, 0x31, - 0x32, 0x73, 0x31, 0x32, 0x74, 0x31, 0x61, 0x30, 0x31, 0x61, 0x31, 0x61, - 0x32, 0x31, 0x61, 0x61, 0x31, 0x61, 0x63, 0x31, 0x61, 0x65, 0x31, 0x61, - 0x69, 0x31, 0x61, 0x6f, 0x31, 0x61, 0x73, 0x31, 0x61, 0x74}; -const uint16_t HuffDecoderCommon::table1_17_inner_[22] = { - 0x000f, 0x00cf, 0x014f, 0x020f, 0x02cf, 0x038f, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x088f, 0x094f, 0x0a0f, - 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_18_emit_[58] = { - 0x31, 0x63, 0x30, 0x31, 0x63, 0x31, 0x63, 0x32, 0x31, 0x63, 0x61, 0x31, - 0x63, 0x63, 0x31, 0x63, 0x65, 0x31, 0x63, 0x69, 0x31, 0x63, 0x6f, 0x31, - 0x63, 0x73, 0x31, 0x63, 0x74, 0x31, 0x65, 0x30, 0x31, 0x65, 0x31, 0x65, - 0x32, 0x31, 0x65, 0x61, 0x31, 0x65, 0x63, 0x31, 0x65, 0x65, 0x31, 0x65, - 0x69, 0x31, 0x65, 0x6f, 0x31, 0x65, 0x73, 0x31, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_19_emit_[58] = { - 0x31, 0x69, 0x30, 0x31, 0x69, 0x31, 0x69, 0x32, 0x31, 0x69, 0x61, 0x31, - 0x69, 0x63, 0x31, 0x69, 0x65, 0x31, 0x69, 0x69, 0x31, 0x69, 0x6f, 0x31, - 0x69, 0x73, 0x31, 0x69, 0x74, 0x31, 0x6f, 0x30, 0x31, 0x6f, 0x31, 0x6f, - 0x32, 0x31, 0x6f, 0x61, 0x31, 0x6f, 0x63, 0x31, 0x6f, 0x65, 0x31, 0x6f, - 0x69, 0x31, 0x6f, 0x6f, 0x31, 0x6f, 0x73, 0x31, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_20_emit_[58] = { - 0x31, 0x73, 0x30, 0x31, 0x73, 0x31, 0x73, 0x32, 0x31, 0x73, 0x61, 0x31, - 0x73, 0x63, 0x31, 0x73, 0x65, 0x31, 0x73, 0x69, 0x31, 0x73, 0x6f, 0x31, - 0x73, 0x73, 0x31, 0x73, 0x74, 0x31, 0x74, 0x30, 0x31, 0x74, 0x31, 0x74, - 0x32, 0x31, 0x74, 0x61, 0x31, 0x74, 0x63, 0x31, 0x74, 0x65, 0x31, 0x74, - 0x69, 0x31, 0x74, 0x6f, 0x31, 0x74, 0x73, 0x31, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_21_emit_[8] = {0x31, 0x20, 0x31, 0x25, - 0x31, 0x2d, 0x31, 0x2e}; -const uint8_t HuffDecoderCommon::table1_22_emit_[8] = {0x31, 0x2f, 0x31, 0x33, - 0x31, 0x34, 0x31, 0x35}; -const uint8_t HuffDecoderCommon::table1_23_emit_[8] = {0x31, 0x36, 0x31, 0x37, - 0x31, 0x38, 0x31, 0x39}; -const uint8_t HuffDecoderCommon::table1_24_emit_[8] = {0x31, 0x3d, 0x31, 0x41, - 0x31, 0x5f, 0x31, 0x62}; -const uint8_t HuffDecoderCommon::table1_25_emit_[8] = {0x31, 0x64, 0x31, 0x66, - 0x31, 0x67, 0x31, 0x68}; -const uint8_t HuffDecoderCommon::table1_26_emit_[8] = {0x31, 0x6c, 0x31, 0x6d, - 0x31, 0x6e, 0x31, 0x70}; -const uint8_t HuffDecoderCommon::table1_27_emit_[12] = { - 0x31, 0x72, 0x31, 0x75, 0x31, 0x3a, 0x31, 0x42, 0x31, 0x43, 0x31, 0x44}; -const uint8_t HuffDecoderCommon::table1_28_emit_[16] = { - 0x31, 0x45, 0x31, 0x46, 0x31, 0x47, 0x31, 0x48, - 0x31, 0x49, 0x31, 0x4a, 0x31, 0x4b, 0x31, 0x4c}; -const uint8_t HuffDecoderCommon::table1_29_emit_[16] = { - 0x31, 0x4d, 0x31, 0x4e, 0x31, 0x4f, 0x31, 0x50, - 0x31, 0x51, 0x31, 0x52, 0x31, 0x53, 0x31, 0x54}; -const uint8_t HuffDecoderCommon::table1_30_emit_[16] = { - 0x31, 0x55, 0x31, 0x56, 0x31, 0x57, 0x31, 0x59, - 0x31, 0x6a, 0x31, 0x6b, 0x31, 0x71, 0x31, 0x76}; -const uint8_t HuffDecoderCommon::table1_31_emit_[30] = { - 0x31, 0x77, 0x31, 0x78, 0x31, 0x79, 0x31, 0x7a, 0x31, 0x26, - 0x31, 0x2a, 0x31, 0x2c, 0x31, 0x3b, 0x31, 0x58, 0x31, 0x5a, - 0x31, 0x21, 0x31, 0x22, 0x31, 0x28, 0x31, 0x29, 0x31, 0x3f}; -const uint8_t HuffDecoderCommon::table1_32_emit_[58] = { - 0x32, 0x30, 0x30, 0x32, 0x30, 0x31, 0x32, 0x30, 0x32, 0x30, 0x61, 0x32, - 0x30, 0x63, 0x32, 0x30, 0x65, 0x32, 0x30, 0x69, 0x32, 0x30, 0x6f, 0x32, - 0x30, 0x73, 0x32, 0x30, 0x74, 0x32, 0x31, 0x30, 0x32, 0x31, 0x31, 0x32, - 0x31, 0x32, 0x31, 0x61, 0x32, 0x31, 0x63, 0x32, 0x31, 0x65, 0x32, 0x31, - 0x69, 0x32, 0x31, 0x6f, 0x32, 0x31, 0x73, 0x32, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_32_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x020f, 0x02cf, 0x038f, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x094f, 0x0a0f, - 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_33_emit_[55] = { - 0x32, 0x32, 0x30, 0x32, 0x32, 0x31, 0x32, 0x32, 0x32, 0x61, 0x32, - 0x32, 0x63, 0x32, 0x32, 0x65, 0x32, 0x32, 0x69, 0x32, 0x32, 0x6f, - 0x32, 0x32, 0x73, 0x32, 0x32, 0x74, 0x32, 0x61, 0x30, 0x32, 0x61, - 0x31, 0x32, 0x61, 0x61, 0x32, 0x61, 0x63, 0x32, 0x61, 0x65, 0x32, - 0x61, 0x69, 0x32, 0x61, 0x6f, 0x32, 0x61, 0x73, 0x32, 0x61, 0x74}; -const uint16_t HuffDecoderCommon::table1_33_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x01cf, 0x028f, 0x034f, 0x040f, 0x04cf, - 0x058f, 0x064f, 0x001a, 0x070f, 0x07cf, 0x020f, 0x088f, 0x094f, - 0x0a0f, 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x021a}; -const uint8_t HuffDecoderCommon::table1_34_emit_[58] = { - 0x32, 0x63, 0x30, 0x32, 0x63, 0x31, 0x32, 0x63, 0x32, 0x63, 0x61, 0x32, - 0x63, 0x63, 0x32, 0x63, 0x65, 0x32, 0x63, 0x69, 0x32, 0x63, 0x6f, 0x32, - 0x63, 0x73, 0x32, 0x63, 0x74, 0x32, 0x65, 0x30, 0x32, 0x65, 0x31, 0x32, - 0x65, 0x32, 0x65, 0x61, 0x32, 0x65, 0x63, 0x32, 0x65, 0x65, 0x32, 0x65, - 0x69, 0x32, 0x65, 0x6f, 0x32, 0x65, 0x73, 0x32, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_35_emit_[58] = { - 0x32, 0x69, 0x30, 0x32, 0x69, 0x31, 0x32, 0x69, 0x32, 0x69, 0x61, 0x32, - 0x69, 0x63, 0x32, 0x69, 0x65, 0x32, 0x69, 0x69, 0x32, 0x69, 0x6f, 0x32, - 0x69, 0x73, 0x32, 0x69, 0x74, 0x32, 0x6f, 0x30, 0x32, 0x6f, 0x31, 0x32, - 0x6f, 0x32, 0x6f, 0x61, 0x32, 0x6f, 0x63, 0x32, 0x6f, 0x65, 0x32, 0x6f, - 0x69, 0x32, 0x6f, 0x6f, 0x32, 0x6f, 0x73, 0x32, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_36_emit_[58] = { - 0x32, 0x73, 0x30, 0x32, 0x73, 0x31, 0x32, 0x73, 0x32, 0x73, 0x61, 0x32, - 0x73, 0x63, 0x32, 0x73, 0x65, 0x32, 0x73, 0x69, 0x32, 0x73, 0x6f, 0x32, - 0x73, 0x73, 0x32, 0x73, 0x74, 0x32, 0x74, 0x30, 0x32, 0x74, 0x31, 0x32, - 0x74, 0x32, 0x74, 0x61, 0x32, 0x74, 0x63, 0x32, 0x74, 0x65, 0x32, 0x74, - 0x69, 0x32, 0x74, 0x6f, 0x32, 0x74, 0x73, 0x32, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_37_emit_[8] = {0x32, 0x20, 0x32, 0x25, - 0x32, 0x2d, 0x32, 0x2e}; -const uint8_t HuffDecoderCommon::table1_38_emit_[8] = {0x32, 0x2f, 0x32, 0x33, - 0x32, 0x34, 0x32, 0x35}; -const uint8_t HuffDecoderCommon::table1_39_emit_[8] = {0x32, 0x36, 0x32, 0x37, - 0x32, 0x38, 0x32, 0x39}; -const uint8_t HuffDecoderCommon::table1_40_emit_[8] = {0x32, 0x3d, 0x32, 0x41, - 0x32, 0x5f, 0x32, 0x62}; -const uint8_t HuffDecoderCommon::table1_41_emit_[8] = {0x32, 0x64, 0x32, 0x66, - 0x32, 0x67, 0x32, 0x68}; -const uint8_t HuffDecoderCommon::table1_42_emit_[8] = {0x32, 0x6c, 0x32, 0x6d, - 0x32, 0x6e, 0x32, 0x70}; -const uint8_t HuffDecoderCommon::table1_43_emit_[12] = { - 0x32, 0x72, 0x32, 0x75, 0x32, 0x3a, 0x32, 0x42, 0x32, 0x43, 0x32, 0x44}; -const uint8_t HuffDecoderCommon::table1_44_emit_[16] = { - 0x32, 0x45, 0x32, 0x46, 0x32, 0x47, 0x32, 0x48, - 0x32, 0x49, 0x32, 0x4a, 0x32, 0x4b, 0x32, 0x4c}; -const uint8_t HuffDecoderCommon::table1_45_emit_[16] = { - 0x32, 0x4d, 0x32, 0x4e, 0x32, 0x4f, 0x32, 0x50, - 0x32, 0x51, 0x32, 0x52, 0x32, 0x53, 0x32, 0x54}; -const uint8_t HuffDecoderCommon::table1_46_emit_[16] = { - 0x32, 0x55, 0x32, 0x56, 0x32, 0x57, 0x32, 0x59, - 0x32, 0x6a, 0x32, 0x6b, 0x32, 0x71, 0x32, 0x76}; -const uint8_t HuffDecoderCommon::table1_47_emit_[30] = { - 0x32, 0x77, 0x32, 0x78, 0x32, 0x79, 0x32, 0x7a, 0x32, 0x26, - 0x32, 0x2a, 0x32, 0x2c, 0x32, 0x3b, 0x32, 0x58, 0x32, 0x5a, - 0x32, 0x21, 0x32, 0x22, 0x32, 0x28, 0x32, 0x29, 0x32, 0x3f}; -const uint8_t HuffDecoderCommon::table1_48_emit_[58] = { - 0x61, 0x30, 0x30, 0x61, 0x30, 0x31, 0x61, 0x30, 0x32, 0x61, 0x30, 0x61, - 0x30, 0x63, 0x61, 0x30, 0x65, 0x61, 0x30, 0x69, 0x61, 0x30, 0x6f, 0x61, - 0x30, 0x73, 0x61, 0x30, 0x74, 0x61, 0x31, 0x30, 0x61, 0x31, 0x31, 0x61, - 0x31, 0x32, 0x61, 0x31, 0x61, 0x31, 0x63, 0x61, 0x31, 0x65, 0x61, 0x31, - 0x69, 0x61, 0x31, 0x6f, 0x61, 0x31, 0x73, 0x61, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_48_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x02cf, 0x038f, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a0f, - 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_49_emit_[57] = { - 0x61, 0x32, 0x30, 0x61, 0x32, 0x31, 0x61, 0x32, 0x32, 0x61, 0x32, 0x61, - 0x32, 0x63, 0x61, 0x32, 0x65, 0x61, 0x32, 0x69, 0x61, 0x32, 0x6f, 0x61, - 0x32, 0x73, 0x61, 0x32, 0x74, 0x61, 0x61, 0x30, 0x61, 0x61, 0x31, 0x61, - 0x61, 0x32, 0x61, 0x61, 0x61, 0x63, 0x61, 0x61, 0x65, 0x61, 0x61, 0x69, - 0x61, 0x61, 0x6f, 0x61, 0x61, 0x73, 0x61, 0x61, 0x74}; -const uint16_t HuffDecoderCommon::table1_49_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x02cf, 0x038f, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x09cf, - 0x0a8f, 0x0b4f, 0x0c0f, 0x0ccf, 0x0d8f, 0x075a}; -const uint8_t HuffDecoderCommon::table1_50_emit_[58] = { - 0x61, 0x63, 0x30, 0x61, 0x63, 0x31, 0x61, 0x63, 0x32, 0x61, 0x63, 0x61, - 0x63, 0x63, 0x61, 0x63, 0x65, 0x61, 0x63, 0x69, 0x61, 0x63, 0x6f, 0x61, - 0x63, 0x73, 0x61, 0x63, 0x74, 0x61, 0x65, 0x30, 0x61, 0x65, 0x31, 0x61, - 0x65, 0x32, 0x61, 0x65, 0x61, 0x65, 0x63, 0x61, 0x65, 0x65, 0x61, 0x65, - 0x69, 0x61, 0x65, 0x6f, 0x61, 0x65, 0x73, 0x61, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_51_emit_[58] = { - 0x61, 0x69, 0x30, 0x61, 0x69, 0x31, 0x61, 0x69, 0x32, 0x61, 0x69, 0x61, - 0x69, 0x63, 0x61, 0x69, 0x65, 0x61, 0x69, 0x69, 0x61, 0x69, 0x6f, 0x61, - 0x69, 0x73, 0x61, 0x69, 0x74, 0x61, 0x6f, 0x30, 0x61, 0x6f, 0x31, 0x61, - 0x6f, 0x32, 0x61, 0x6f, 0x61, 0x6f, 0x63, 0x61, 0x6f, 0x65, 0x61, 0x6f, - 0x69, 0x61, 0x6f, 0x6f, 0x61, 0x6f, 0x73, 0x61, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_52_emit_[58] = { - 0x61, 0x73, 0x30, 0x61, 0x73, 0x31, 0x61, 0x73, 0x32, 0x61, 0x73, 0x61, - 0x73, 0x63, 0x61, 0x73, 0x65, 0x61, 0x73, 0x69, 0x61, 0x73, 0x6f, 0x61, - 0x73, 0x73, 0x61, 0x73, 0x74, 0x61, 0x74, 0x30, 0x61, 0x74, 0x31, 0x61, - 0x74, 0x32, 0x61, 0x74, 0x61, 0x74, 0x63, 0x61, 0x74, 0x65, 0x61, 0x74, - 0x69, 0x61, 0x74, 0x6f, 0x61, 0x74, 0x73, 0x61, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_53_emit_[8] = {0x61, 0x20, 0x61, 0x25, - 0x61, 0x2d, 0x61, 0x2e}; -const uint8_t HuffDecoderCommon::table1_54_emit_[8] = {0x61, 0x2f, 0x61, 0x33, - 0x61, 0x34, 0x61, 0x35}; -const uint8_t HuffDecoderCommon::table1_55_emit_[8] = {0x61, 0x36, 0x61, 0x37, - 0x61, 0x38, 0x61, 0x39}; -const uint8_t HuffDecoderCommon::table1_56_emit_[8] = {0x61, 0x3d, 0x61, 0x41, - 0x61, 0x5f, 0x61, 0x62}; -const uint8_t HuffDecoderCommon::table1_57_emit_[8] = {0x61, 0x64, 0x61, 0x66, - 0x61, 0x67, 0x61, 0x68}; -const uint8_t HuffDecoderCommon::table1_58_emit_[8] = {0x61, 0x6c, 0x61, 0x6d, - 0x61, 0x6e, 0x61, 0x70}; -const uint8_t HuffDecoderCommon::table1_59_emit_[12] = { - 0x61, 0x72, 0x61, 0x75, 0x61, 0x3a, 0x61, 0x42, 0x61, 0x43, 0x61, 0x44}; -const uint8_t HuffDecoderCommon::table1_60_emit_[16] = { - 0x61, 0x45, 0x61, 0x46, 0x61, 0x47, 0x61, 0x48, - 0x61, 0x49, 0x61, 0x4a, 0x61, 0x4b, 0x61, 0x4c}; -const uint8_t HuffDecoderCommon::table1_61_emit_[16] = { - 0x61, 0x4d, 0x61, 0x4e, 0x61, 0x4f, 0x61, 0x50, - 0x61, 0x51, 0x61, 0x52, 0x61, 0x53, 0x61, 0x54}; -const uint8_t HuffDecoderCommon::table1_62_emit_[16] = { - 0x61, 0x55, 0x61, 0x56, 0x61, 0x57, 0x61, 0x59, - 0x61, 0x6a, 0x61, 0x6b, 0x61, 0x71, 0x61, 0x76}; -const uint8_t HuffDecoderCommon::table1_63_emit_[30] = { - 0x61, 0x77, 0x61, 0x78, 0x61, 0x79, 0x61, 0x7a, 0x61, 0x26, - 0x61, 0x2a, 0x61, 0x2c, 0x61, 0x3b, 0x61, 0x58, 0x61, 0x5a, - 0x61, 0x21, 0x61, 0x22, 0x61, 0x28, 0x61, 0x29, 0x61, 0x3f}; -const uint8_t HuffDecoderCommon::table1_64_emit_[58] = { - 0x63, 0x30, 0x30, 0x63, 0x30, 0x31, 0x63, 0x30, 0x32, 0x63, 0x30, 0x61, - 0x63, 0x30, 0x63, 0x30, 0x65, 0x63, 0x30, 0x69, 0x63, 0x30, 0x6f, 0x63, - 0x30, 0x73, 0x63, 0x30, 0x74, 0x63, 0x31, 0x30, 0x63, 0x31, 0x31, 0x63, - 0x31, 0x32, 0x63, 0x31, 0x61, 0x63, 0x31, 0x63, 0x31, 0x65, 0x63, 0x31, - 0x69, 0x63, 0x31, 0x6f, 0x63, 0x31, 0x73, 0x63, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_64_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x038f, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_65_emit_[58] = { - 0x63, 0x32, 0x30, 0x63, 0x32, 0x31, 0x63, 0x32, 0x32, 0x63, 0x32, 0x61, - 0x63, 0x32, 0x63, 0x32, 0x65, 0x63, 0x32, 0x69, 0x63, 0x32, 0x6f, 0x63, - 0x32, 0x73, 0x63, 0x32, 0x74, 0x63, 0x61, 0x30, 0x63, 0x61, 0x31, 0x63, - 0x61, 0x32, 0x63, 0x61, 0x61, 0x63, 0x61, 0x63, 0x61, 0x65, 0x63, 0x61, - 0x69, 0x63, 0x61, 0x6f, 0x63, 0x61, 0x73, 0x63, 0x61, 0x74}; -const uint8_t HuffDecoderCommon::table1_66_emit_[55] = { - 0x63, 0x63, 0x30, 0x63, 0x63, 0x31, 0x63, 0x63, 0x32, 0x63, 0x63, - 0x61, 0x63, 0x63, 0x63, 0x65, 0x63, 0x63, 0x69, 0x63, 0x63, 0x6f, - 0x63, 0x63, 0x73, 0x63, 0x63, 0x74, 0x63, 0x65, 0x30, 0x63, 0x65, - 0x31, 0x63, 0x65, 0x32, 0x63, 0x65, 0x61, 0x63, 0x65, 0x65, 0x63, - 0x65, 0x69, 0x63, 0x65, 0x6f, 0x63, 0x65, 0x73, 0x63, 0x65, 0x74}; -const uint16_t HuffDecoderCommon::table1_66_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x034f, 0x040f, 0x04cf, - 0x058f, 0x064f, 0x001a, 0x070f, 0x07cf, 0x088f, 0x094f, 0x038f, - 0x0a0f, 0x0acf, 0x0b8f, 0x0c4f, 0x0d0f, 0x039a}; -const uint8_t HuffDecoderCommon::table1_67_emit_[58] = { - 0x63, 0x69, 0x30, 0x63, 0x69, 0x31, 0x63, 0x69, 0x32, 0x63, 0x69, 0x61, - 0x63, 0x69, 0x63, 0x69, 0x65, 0x63, 0x69, 0x69, 0x63, 0x69, 0x6f, 0x63, - 0x69, 0x73, 0x63, 0x69, 0x74, 0x63, 0x6f, 0x30, 0x63, 0x6f, 0x31, 0x63, - 0x6f, 0x32, 0x63, 0x6f, 0x61, 0x63, 0x6f, 0x63, 0x6f, 0x65, 0x63, 0x6f, - 0x69, 0x63, 0x6f, 0x6f, 0x63, 0x6f, 0x73, 0x63, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_68_emit_[58] = { - 0x63, 0x73, 0x30, 0x63, 0x73, 0x31, 0x63, 0x73, 0x32, 0x63, 0x73, 0x61, - 0x63, 0x73, 0x63, 0x73, 0x65, 0x63, 0x73, 0x69, 0x63, 0x73, 0x6f, 0x63, - 0x73, 0x73, 0x63, 0x73, 0x74, 0x63, 0x74, 0x30, 0x63, 0x74, 0x31, 0x63, - 0x74, 0x32, 0x63, 0x74, 0x61, 0x63, 0x74, 0x63, 0x74, 0x65, 0x63, 0x74, - 0x69, 0x63, 0x74, 0x6f, 0x63, 0x74, 0x73, 0x63, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_69_emit_[8] = {0x63, 0x20, 0x63, 0x25, - 0x63, 0x2d, 0x63, 0x2e}; -const uint8_t HuffDecoderCommon::table1_70_emit_[8] = {0x63, 0x2f, 0x63, 0x33, - 0x63, 0x34, 0x63, 0x35}; -const uint8_t HuffDecoderCommon::table1_71_emit_[8] = {0x63, 0x36, 0x63, 0x37, - 0x63, 0x38, 0x63, 0x39}; -const uint8_t HuffDecoderCommon::table1_72_emit_[8] = {0x63, 0x3d, 0x63, 0x41, - 0x63, 0x5f, 0x63, 0x62}; -const uint8_t HuffDecoderCommon::table1_73_emit_[8] = {0x63, 0x64, 0x63, 0x66, - 0x63, 0x67, 0x63, 0x68}; -const uint8_t HuffDecoderCommon::table1_74_emit_[8] = {0x63, 0x6c, 0x63, 0x6d, - 0x63, 0x6e, 0x63, 0x70}; -const uint8_t HuffDecoderCommon::table1_75_emit_[12] = { - 0x63, 0x72, 0x63, 0x75, 0x63, 0x3a, 0x63, 0x42, 0x63, 0x43, 0x63, 0x44}; -const uint8_t HuffDecoderCommon::table1_76_emit_[16] = { - 0x63, 0x45, 0x63, 0x46, 0x63, 0x47, 0x63, 0x48, - 0x63, 0x49, 0x63, 0x4a, 0x63, 0x4b, 0x63, 0x4c}; -const uint8_t HuffDecoderCommon::table1_77_emit_[16] = { - 0x63, 0x4d, 0x63, 0x4e, 0x63, 0x4f, 0x63, 0x50, - 0x63, 0x51, 0x63, 0x52, 0x63, 0x53, 0x63, 0x54}; -const uint8_t HuffDecoderCommon::table1_78_emit_[16] = { - 0x63, 0x55, 0x63, 0x56, 0x63, 0x57, 0x63, 0x59, - 0x63, 0x6a, 0x63, 0x6b, 0x63, 0x71, 0x63, 0x76}; -const uint8_t HuffDecoderCommon::table1_79_emit_[30] = { - 0x63, 0x77, 0x63, 0x78, 0x63, 0x79, 0x63, 0x7a, 0x63, 0x26, - 0x63, 0x2a, 0x63, 0x2c, 0x63, 0x3b, 0x63, 0x58, 0x63, 0x5a, - 0x63, 0x21, 0x63, 0x22, 0x63, 0x28, 0x63, 0x29, 0x63, 0x3f}; -const uint8_t HuffDecoderCommon::table1_80_emit_[58] = { - 0x65, 0x30, 0x30, 0x65, 0x30, 0x31, 0x65, 0x30, 0x32, 0x65, 0x30, 0x61, - 0x65, 0x30, 0x63, 0x65, 0x30, 0x65, 0x30, 0x69, 0x65, 0x30, 0x6f, 0x65, - 0x30, 0x73, 0x65, 0x30, 0x74, 0x65, 0x31, 0x30, 0x65, 0x31, 0x31, 0x65, - 0x31, 0x32, 0x65, 0x31, 0x61, 0x65, 0x31, 0x63, 0x65, 0x31, 0x65, 0x31, - 0x69, 0x65, 0x31, 0x6f, 0x65, 0x31, 0x73, 0x65, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_80_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0b0f, 0x0b8f, 0x0c4f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_81_emit_[58] = { - 0x65, 0x32, 0x30, 0x65, 0x32, 0x31, 0x65, 0x32, 0x32, 0x65, 0x32, 0x61, - 0x65, 0x32, 0x63, 0x65, 0x32, 0x65, 0x32, 0x69, 0x65, 0x32, 0x6f, 0x65, - 0x32, 0x73, 0x65, 0x32, 0x74, 0x65, 0x61, 0x30, 0x65, 0x61, 0x31, 0x65, - 0x61, 0x32, 0x65, 0x61, 0x61, 0x65, 0x61, 0x63, 0x65, 0x61, 0x65, 0x61, - 0x69, 0x65, 0x61, 0x6f, 0x65, 0x61, 0x73, 0x65, 0x61, 0x74}; -const uint8_t HuffDecoderCommon::table1_82_emit_[57] = { - 0x65, 0x63, 0x30, 0x65, 0x63, 0x31, 0x65, 0x63, 0x32, 0x65, 0x63, 0x61, - 0x65, 0x63, 0x63, 0x65, 0x63, 0x65, 0x63, 0x69, 0x65, 0x63, 0x6f, 0x65, - 0x63, 0x73, 0x65, 0x63, 0x74, 0x65, 0x65, 0x30, 0x65, 0x65, 0x31, 0x65, - 0x65, 0x32, 0x65, 0x65, 0x61, 0x65, 0x65, 0x63, 0x65, 0x65, 0x65, 0x69, - 0x65, 0x65, 0x6f, 0x65, 0x65, 0x73, 0x65, 0x65, 0x74}; -const uint16_t HuffDecoderCommon::table1_82_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x044f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0b0f, 0x0b4f, 0x0c0f, 0x0ccf, 0x0d8f, 0x075a}; -const uint8_t HuffDecoderCommon::table1_83_emit_[58] = { - 0x65, 0x69, 0x30, 0x65, 0x69, 0x31, 0x65, 0x69, 0x32, 0x65, 0x69, 0x61, - 0x65, 0x69, 0x63, 0x65, 0x69, 0x65, 0x69, 0x69, 0x65, 0x69, 0x6f, 0x65, - 0x69, 0x73, 0x65, 0x69, 0x74, 0x65, 0x6f, 0x30, 0x65, 0x6f, 0x31, 0x65, - 0x6f, 0x32, 0x65, 0x6f, 0x61, 0x65, 0x6f, 0x63, 0x65, 0x6f, 0x65, 0x6f, - 0x69, 0x65, 0x6f, 0x6f, 0x65, 0x6f, 0x73, 0x65, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_84_emit_[58] = { - 0x65, 0x73, 0x30, 0x65, 0x73, 0x31, 0x65, 0x73, 0x32, 0x65, 0x73, 0x61, - 0x65, 0x73, 0x63, 0x65, 0x73, 0x65, 0x73, 0x69, 0x65, 0x73, 0x6f, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x74, 0x65, 0x74, 0x30, 0x65, 0x74, 0x31, 0x65, - 0x74, 0x32, 0x65, 0x74, 0x61, 0x65, 0x74, 0x63, 0x65, 0x74, 0x65, 0x74, - 0x69, 0x65, 0x74, 0x6f, 0x65, 0x74, 0x73, 0x65, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_85_emit_[8] = {0x65, 0x20, 0x65, 0x25, - 0x65, 0x2d, 0x65, 0x2e}; -const uint8_t HuffDecoderCommon::table1_86_emit_[8] = {0x65, 0x2f, 0x65, 0x33, - 0x65, 0x34, 0x65, 0x35}; -const uint8_t HuffDecoderCommon::table1_87_emit_[8] = {0x65, 0x36, 0x65, 0x37, - 0x65, 0x38, 0x65, 0x39}; -const uint8_t HuffDecoderCommon::table1_88_emit_[8] = {0x65, 0x3d, 0x65, 0x41, - 0x65, 0x5f, 0x65, 0x62}; -const uint8_t HuffDecoderCommon::table1_89_emit_[8] = {0x65, 0x64, 0x65, 0x66, - 0x65, 0x67, 0x65, 0x68}; -const uint8_t HuffDecoderCommon::table1_90_emit_[8] = {0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x65, 0x70}; -const uint8_t HuffDecoderCommon::table1_91_emit_[12] = { - 0x65, 0x72, 0x65, 0x75, 0x65, 0x3a, 0x65, 0x42, 0x65, 0x43, 0x65, 0x44}; -const uint8_t HuffDecoderCommon::table1_92_emit_[16] = { - 0x65, 0x45, 0x65, 0x46, 0x65, 0x47, 0x65, 0x48, - 0x65, 0x49, 0x65, 0x4a, 0x65, 0x4b, 0x65, 0x4c}; -const uint8_t HuffDecoderCommon::table1_93_emit_[16] = { - 0x65, 0x4d, 0x65, 0x4e, 0x65, 0x4f, 0x65, 0x50, - 0x65, 0x51, 0x65, 0x52, 0x65, 0x53, 0x65, 0x54}; -const uint8_t HuffDecoderCommon::table1_94_emit_[16] = { - 0x65, 0x55, 0x65, 0x56, 0x65, 0x57, 0x65, 0x59, - 0x65, 0x6a, 0x65, 0x6b, 0x65, 0x71, 0x65, 0x76}; -const uint8_t HuffDecoderCommon::table1_95_emit_[30] = { - 0x65, 0x77, 0x65, 0x78, 0x65, 0x79, 0x65, 0x7a, 0x65, 0x26, - 0x65, 0x2a, 0x65, 0x2c, 0x65, 0x3b, 0x65, 0x58, 0x65, 0x5a, - 0x65, 0x21, 0x65, 0x22, 0x65, 0x28, 0x65, 0x29, 0x65, 0x3f}; -const uint8_t HuffDecoderCommon::table1_96_emit_[58] = { - 0x69, 0x30, 0x30, 0x69, 0x30, 0x31, 0x69, 0x30, 0x32, 0x69, 0x30, 0x61, - 0x69, 0x30, 0x63, 0x69, 0x30, 0x65, 0x69, 0x30, 0x69, 0x30, 0x6f, 0x69, - 0x30, 0x73, 0x69, 0x30, 0x74, 0x69, 0x31, 0x30, 0x69, 0x31, 0x31, 0x69, - 0x31, 0x32, 0x69, 0x31, 0x61, 0x69, 0x31, 0x63, 0x69, 0x31, 0x65, 0x69, - 0x31, 0x69, 0x31, 0x6f, 0x69, 0x31, 0x73, 0x69, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_96_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x048f, 0x050f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0b0f, 0x0bcf, 0x0c4f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_97_emit_[58] = { - 0x69, 0x32, 0x30, 0x69, 0x32, 0x31, 0x69, 0x32, 0x32, 0x69, 0x32, 0x61, - 0x69, 0x32, 0x63, 0x69, 0x32, 0x65, 0x69, 0x32, 0x69, 0x32, 0x6f, 0x69, - 0x32, 0x73, 0x69, 0x32, 0x74, 0x69, 0x61, 0x30, 0x69, 0x61, 0x31, 0x69, - 0x61, 0x32, 0x69, 0x61, 0x61, 0x69, 0x61, 0x63, 0x69, 0x61, 0x65, 0x69, - 0x61, 0x69, 0x61, 0x6f, 0x69, 0x61, 0x73, 0x69, 0x61, 0x74}; -const uint8_t HuffDecoderCommon::table1_98_emit_[58] = { - 0x69, 0x63, 0x30, 0x69, 0x63, 0x31, 0x69, 0x63, 0x32, 0x69, 0x63, 0x61, - 0x69, 0x63, 0x63, 0x69, 0x63, 0x65, 0x69, 0x63, 0x69, 0x63, 0x6f, 0x69, - 0x63, 0x73, 0x69, 0x63, 0x74, 0x69, 0x65, 0x30, 0x69, 0x65, 0x31, 0x69, - 0x65, 0x32, 0x69, 0x65, 0x61, 0x69, 0x65, 0x63, 0x69, 0x65, 0x65, 0x69, - 0x65, 0x69, 0x65, 0x6f, 0x69, 0x65, 0x73, 0x69, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_99_emit_[55] = { - 0x69, 0x69, 0x30, 0x69, 0x69, 0x31, 0x69, 0x69, 0x32, 0x69, 0x69, - 0x61, 0x69, 0x69, 0x63, 0x69, 0x69, 0x65, 0x69, 0x69, 0x69, 0x6f, - 0x69, 0x69, 0x73, 0x69, 0x69, 0x74, 0x69, 0x6f, 0x30, 0x69, 0x6f, - 0x31, 0x69, 0x6f, 0x32, 0x69, 0x6f, 0x61, 0x69, 0x6f, 0x63, 0x69, - 0x6f, 0x65, 0x69, 0x6f, 0x6f, 0x69, 0x6f, 0x73, 0x69, 0x6f, 0x74}; -const uint16_t HuffDecoderCommon::table1_99_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x048f, 0x04cf, - 0x058f, 0x064f, 0x001a, 0x070f, 0x07cf, 0x088f, 0x094f, 0x0a0f, - 0x0acf, 0x050f, 0x0b8f, 0x0c4f, 0x0d0f, 0x051a}; -const uint8_t HuffDecoderCommon::table1_100_emit_[58] = { - 0x69, 0x73, 0x30, 0x69, 0x73, 0x31, 0x69, 0x73, 0x32, 0x69, 0x73, 0x61, - 0x69, 0x73, 0x63, 0x69, 0x73, 0x65, 0x69, 0x73, 0x69, 0x73, 0x6f, 0x69, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x69, 0x74, 0x30, 0x69, 0x74, 0x31, 0x69, - 0x74, 0x32, 0x69, 0x74, 0x61, 0x69, 0x74, 0x63, 0x69, 0x74, 0x65, 0x69, - 0x74, 0x69, 0x74, 0x6f, 0x69, 0x74, 0x73, 0x69, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_101_emit_[8] = {0x69, 0x20, 0x69, 0x25, - 0x69, 0x2d, 0x69, 0x2e}; -const uint8_t HuffDecoderCommon::table1_102_emit_[8] = {0x69, 0x2f, 0x69, 0x33, - 0x69, 0x34, 0x69, 0x35}; -const uint8_t HuffDecoderCommon::table1_103_emit_[8] = {0x69, 0x36, 0x69, 0x37, - 0x69, 0x38, 0x69, 0x39}; -const uint8_t HuffDecoderCommon::table1_104_emit_[8] = {0x69, 0x3d, 0x69, 0x41, - 0x69, 0x5f, 0x69, 0x62}; -const uint8_t HuffDecoderCommon::table1_105_emit_[8] = {0x69, 0x64, 0x69, 0x66, - 0x69, 0x67, 0x69, 0x68}; -const uint8_t HuffDecoderCommon::table1_106_emit_[8] = {0x69, 0x6c, 0x69, 0x6d, - 0x69, 0x6e, 0x69, 0x70}; -const uint8_t HuffDecoderCommon::table1_107_emit_[12] = { - 0x69, 0x72, 0x69, 0x75, 0x69, 0x3a, 0x69, 0x42, 0x69, 0x43, 0x69, 0x44}; -const uint8_t HuffDecoderCommon::table1_108_emit_[16] = { - 0x69, 0x45, 0x69, 0x46, 0x69, 0x47, 0x69, 0x48, - 0x69, 0x49, 0x69, 0x4a, 0x69, 0x4b, 0x69, 0x4c}; -const uint8_t HuffDecoderCommon::table1_109_emit_[16] = { - 0x69, 0x4d, 0x69, 0x4e, 0x69, 0x4f, 0x69, 0x50, - 0x69, 0x51, 0x69, 0x52, 0x69, 0x53, 0x69, 0x54}; -const uint8_t HuffDecoderCommon::table1_110_emit_[16] = { - 0x69, 0x55, 0x69, 0x56, 0x69, 0x57, 0x69, 0x59, - 0x69, 0x6a, 0x69, 0x6b, 0x69, 0x71, 0x69, 0x76}; -const uint8_t HuffDecoderCommon::table1_111_emit_[30] = { - 0x69, 0x77, 0x69, 0x78, 0x69, 0x79, 0x69, 0x7a, 0x69, 0x26, - 0x69, 0x2a, 0x69, 0x2c, 0x69, 0x3b, 0x69, 0x58, 0x69, 0x5a, - 0x69, 0x21, 0x69, 0x22, 0x69, 0x28, 0x69, 0x29, 0x69, 0x3f}; -const uint8_t HuffDecoderCommon::table1_112_emit_[58] = { - 0x6f, 0x30, 0x30, 0x6f, 0x30, 0x31, 0x6f, 0x30, 0x32, 0x6f, 0x30, 0x61, - 0x6f, 0x30, 0x63, 0x6f, 0x30, 0x65, 0x6f, 0x30, 0x69, 0x6f, 0x30, 0x6f, - 0x30, 0x73, 0x6f, 0x30, 0x74, 0x6f, 0x31, 0x30, 0x6f, 0x31, 0x31, 0x6f, - 0x31, 0x32, 0x6f, 0x31, 0x61, 0x6f, 0x31, 0x63, 0x6f, 0x31, 0x65, 0x6f, - 0x31, 0x69, 0x6f, 0x31, 0x6f, 0x31, 0x73, 0x6f, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_112_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x048f, 0x054f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0b0f, 0x0bcf, 0x0c8f, 0x0d0f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_113_emit_[58] = { - 0x6f, 0x32, 0x30, 0x6f, 0x32, 0x31, 0x6f, 0x32, 0x32, 0x6f, 0x32, 0x61, - 0x6f, 0x32, 0x63, 0x6f, 0x32, 0x65, 0x6f, 0x32, 0x69, 0x6f, 0x32, 0x6f, - 0x32, 0x73, 0x6f, 0x32, 0x74, 0x6f, 0x61, 0x30, 0x6f, 0x61, 0x31, 0x6f, - 0x61, 0x32, 0x6f, 0x61, 0x61, 0x6f, 0x61, 0x63, 0x6f, 0x61, 0x65, 0x6f, - 0x61, 0x69, 0x6f, 0x61, 0x6f, 0x61, 0x73, 0x6f, 0x61, 0x74}; -const uint8_t HuffDecoderCommon::table1_114_emit_[58] = { - 0x6f, 0x63, 0x30, 0x6f, 0x63, 0x31, 0x6f, 0x63, 0x32, 0x6f, 0x63, 0x61, - 0x6f, 0x63, 0x63, 0x6f, 0x63, 0x65, 0x6f, 0x63, 0x69, 0x6f, 0x63, 0x6f, - 0x63, 0x73, 0x6f, 0x63, 0x74, 0x6f, 0x65, 0x30, 0x6f, 0x65, 0x31, 0x6f, - 0x65, 0x32, 0x6f, 0x65, 0x61, 0x6f, 0x65, 0x63, 0x6f, 0x65, 0x65, 0x6f, - 0x65, 0x69, 0x6f, 0x65, 0x6f, 0x65, 0x73, 0x6f, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_115_emit_[57] = { - 0x6f, 0x69, 0x30, 0x6f, 0x69, 0x31, 0x6f, 0x69, 0x32, 0x6f, 0x69, 0x61, - 0x6f, 0x69, 0x63, 0x6f, 0x69, 0x65, 0x6f, 0x69, 0x69, 0x6f, 0x69, 0x6f, - 0x69, 0x73, 0x6f, 0x69, 0x74, 0x6f, 0x6f, 0x30, 0x6f, 0x6f, 0x31, 0x6f, - 0x6f, 0x32, 0x6f, 0x6f, 0x61, 0x6f, 0x6f, 0x63, 0x6f, 0x6f, 0x65, 0x6f, - 0x6f, 0x69, 0x6f, 0x6f, 0x6f, 0x73, 0x6f, 0x6f, 0x74}; -const uint16_t HuffDecoderCommon::table1_115_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x048f, 0x054f, - 0x05cf, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0b0f, 0x0bcf, 0x0c8f, 0x0ccf, 0x0d8f, 0x075a}; -const uint8_t HuffDecoderCommon::table1_116_emit_[58] = { - 0x6f, 0x73, 0x30, 0x6f, 0x73, 0x31, 0x6f, 0x73, 0x32, 0x6f, 0x73, 0x61, - 0x6f, 0x73, 0x63, 0x6f, 0x73, 0x65, 0x6f, 0x73, 0x69, 0x6f, 0x73, 0x6f, - 0x73, 0x73, 0x6f, 0x73, 0x74, 0x6f, 0x74, 0x30, 0x6f, 0x74, 0x31, 0x6f, - 0x74, 0x32, 0x6f, 0x74, 0x61, 0x6f, 0x74, 0x63, 0x6f, 0x74, 0x65, 0x6f, - 0x74, 0x69, 0x6f, 0x74, 0x6f, 0x74, 0x73, 0x6f, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_117_emit_[8] = {0x6f, 0x20, 0x6f, 0x25, - 0x6f, 0x2d, 0x6f, 0x2e}; -const uint8_t HuffDecoderCommon::table1_118_emit_[8] = {0x6f, 0x2f, 0x6f, 0x33, - 0x6f, 0x34, 0x6f, 0x35}; -const uint8_t HuffDecoderCommon::table1_119_emit_[8] = {0x6f, 0x36, 0x6f, 0x37, - 0x6f, 0x38, 0x6f, 0x39}; -const uint8_t HuffDecoderCommon::table1_120_emit_[8] = {0x6f, 0x3d, 0x6f, 0x41, - 0x6f, 0x5f, 0x6f, 0x62}; -const uint8_t HuffDecoderCommon::table1_121_emit_[8] = {0x6f, 0x64, 0x6f, 0x66, - 0x6f, 0x67, 0x6f, 0x68}; -const uint8_t HuffDecoderCommon::table1_122_emit_[8] = {0x6f, 0x6c, 0x6f, 0x6d, - 0x6f, 0x6e, 0x6f, 0x70}; -const uint8_t HuffDecoderCommon::table1_123_emit_[12] = { - 0x6f, 0x72, 0x6f, 0x75, 0x6f, 0x3a, 0x6f, 0x42, 0x6f, 0x43, 0x6f, 0x44}; -const uint8_t HuffDecoderCommon::table1_124_emit_[16] = { - 0x6f, 0x45, 0x6f, 0x46, 0x6f, 0x47, 0x6f, 0x48, - 0x6f, 0x49, 0x6f, 0x4a, 0x6f, 0x4b, 0x6f, 0x4c}; -const uint8_t HuffDecoderCommon::table1_125_emit_[16] = { - 0x6f, 0x4d, 0x6f, 0x4e, 0x6f, 0x4f, 0x6f, 0x50, - 0x6f, 0x51, 0x6f, 0x52, 0x6f, 0x53, 0x6f, 0x54}; -const uint8_t HuffDecoderCommon::table1_126_emit_[16] = { - 0x6f, 0x55, 0x6f, 0x56, 0x6f, 0x57, 0x6f, 0x59, - 0x6f, 0x6a, 0x6f, 0x6b, 0x6f, 0x71, 0x6f, 0x76}; -const uint8_t HuffDecoderCommon::table1_127_emit_[30] = { - 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, 0x26, - 0x6f, 0x2a, 0x6f, 0x2c, 0x6f, 0x3b, 0x6f, 0x58, 0x6f, 0x5a, - 0x6f, 0x21, 0x6f, 0x22, 0x6f, 0x28, 0x6f, 0x29, 0x6f, 0x3f}; -const uint8_t HuffDecoderCommon::table1_128_emit_[58] = { - 0x73, 0x30, 0x30, 0x73, 0x30, 0x31, 0x73, 0x30, 0x32, 0x73, 0x30, 0x61, - 0x73, 0x30, 0x63, 0x73, 0x30, 0x65, 0x73, 0x30, 0x69, 0x73, 0x30, 0x6f, - 0x73, 0x30, 0x73, 0x30, 0x74, 0x73, 0x31, 0x30, 0x73, 0x31, 0x31, 0x73, - 0x31, 0x32, 0x73, 0x31, 0x61, 0x73, 0x31, 0x63, 0x73, 0x31, 0x65, 0x73, - 0x31, 0x69, 0x73, 0x31, 0x6f, 0x73, 0x31, 0x73, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_128_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x048f, 0x054f, - 0x060f, 0x068f, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0b0f, 0x0bcf, 0x0c8f, 0x0d4f, 0x0dcf, 0x075a}; -const uint8_t HuffDecoderCommon::table1_129_emit_[58] = { - 0x73, 0x32, 0x30, 0x73, 0x32, 0x31, 0x73, 0x32, 0x32, 0x73, 0x32, 0x61, - 0x73, 0x32, 0x63, 0x73, 0x32, 0x65, 0x73, 0x32, 0x69, 0x73, 0x32, 0x6f, - 0x73, 0x32, 0x73, 0x32, 0x74, 0x73, 0x61, 0x30, 0x73, 0x61, 0x31, 0x73, - 0x61, 0x32, 0x73, 0x61, 0x61, 0x73, 0x61, 0x63, 0x73, 0x61, 0x65, 0x73, - 0x61, 0x69, 0x73, 0x61, 0x6f, 0x73, 0x61, 0x73, 0x61, 0x74}; -const uint8_t HuffDecoderCommon::table1_130_emit_[58] = { - 0x73, 0x63, 0x30, 0x73, 0x63, 0x31, 0x73, 0x63, 0x32, 0x73, 0x63, 0x61, - 0x73, 0x63, 0x63, 0x73, 0x63, 0x65, 0x73, 0x63, 0x69, 0x73, 0x63, 0x6f, - 0x73, 0x63, 0x73, 0x63, 0x74, 0x73, 0x65, 0x30, 0x73, 0x65, 0x31, 0x73, - 0x65, 0x32, 0x73, 0x65, 0x61, 0x73, 0x65, 0x63, 0x73, 0x65, 0x65, 0x73, - 0x65, 0x69, 0x73, 0x65, 0x6f, 0x73, 0x65, 0x73, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_131_emit_[58] = { - 0x73, 0x69, 0x30, 0x73, 0x69, 0x31, 0x73, 0x69, 0x32, 0x73, 0x69, 0x61, - 0x73, 0x69, 0x63, 0x73, 0x69, 0x65, 0x73, 0x69, 0x69, 0x73, 0x69, 0x6f, - 0x73, 0x69, 0x73, 0x69, 0x74, 0x73, 0x6f, 0x30, 0x73, 0x6f, 0x31, 0x73, - 0x6f, 0x32, 0x73, 0x6f, 0x61, 0x73, 0x6f, 0x63, 0x73, 0x6f, 0x65, 0x73, - 0x6f, 0x69, 0x73, 0x6f, 0x6f, 0x73, 0x6f, 0x73, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_132_emit_[55] = { - 0x73, 0x73, 0x30, 0x73, 0x73, 0x31, 0x73, 0x73, 0x32, 0x73, 0x73, - 0x61, 0x73, 0x73, 0x63, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x73, - 0x73, 0x6f, 0x73, 0x73, 0x73, 0x74, 0x30, 0x73, 0x74, 0x31, 0x73, - 0x74, 0x32, 0x73, 0x74, 0x61, 0x73, 0x74, 0x63, 0x73, 0x74, 0x65, - 0x73, 0x74, 0x69, 0x73, 0x74, 0x6f, 0x73, 0x74, 0x73, 0x74, 0x74}; -const uint16_t HuffDecoderCommon::table1_132_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x048f, 0x054f, - 0x060f, 0x064f, 0x001a, 0x068f, 0x074f, 0x080f, 0x08cf, 0x098f, - 0x0a4f, 0x0b0f, 0x0bcf, 0x0c8f, 0x0d0f, 0x069a}; -const uint8_t HuffDecoderCommon::table1_133_emit_[8] = {0x73, 0x20, 0x73, 0x25, - 0x73, 0x2d, 0x73, 0x2e}; -const uint8_t HuffDecoderCommon::table1_134_emit_[8] = {0x73, 0x2f, 0x73, 0x33, - 0x73, 0x34, 0x73, 0x35}; -const uint8_t HuffDecoderCommon::table1_135_emit_[8] = {0x73, 0x36, 0x73, 0x37, - 0x73, 0x38, 0x73, 0x39}; -const uint8_t HuffDecoderCommon::table1_136_emit_[8] = {0x73, 0x3d, 0x73, 0x41, - 0x73, 0x5f, 0x73, 0x62}; -const uint8_t HuffDecoderCommon::table1_137_emit_[8] = {0x73, 0x64, 0x73, 0x66, - 0x73, 0x67, 0x73, 0x68}; -const uint8_t HuffDecoderCommon::table1_138_emit_[8] = {0x73, 0x6c, 0x73, 0x6d, - 0x73, 0x6e, 0x73, 0x70}; -const uint8_t HuffDecoderCommon::table1_139_emit_[12] = { - 0x73, 0x72, 0x73, 0x75, 0x73, 0x3a, 0x73, 0x42, 0x73, 0x43, 0x73, 0x44}; -const uint8_t HuffDecoderCommon::table1_140_emit_[16] = { - 0x73, 0x45, 0x73, 0x46, 0x73, 0x47, 0x73, 0x48, - 0x73, 0x49, 0x73, 0x4a, 0x73, 0x4b, 0x73, 0x4c}; -const uint8_t HuffDecoderCommon::table1_141_emit_[16] = { - 0x73, 0x4d, 0x73, 0x4e, 0x73, 0x4f, 0x73, 0x50, - 0x73, 0x51, 0x73, 0x52, 0x73, 0x53, 0x73, 0x54}; -const uint8_t HuffDecoderCommon::table1_142_emit_[16] = { - 0x73, 0x55, 0x73, 0x56, 0x73, 0x57, 0x73, 0x59, - 0x73, 0x6a, 0x73, 0x6b, 0x73, 0x71, 0x73, 0x76}; -const uint8_t HuffDecoderCommon::table1_143_emit_[30] = { - 0x73, 0x77, 0x73, 0x78, 0x73, 0x79, 0x73, 0x7a, 0x73, 0x26, - 0x73, 0x2a, 0x73, 0x2c, 0x73, 0x3b, 0x73, 0x58, 0x73, 0x5a, - 0x73, 0x21, 0x73, 0x22, 0x73, 0x28, 0x73, 0x29, 0x73, 0x3f}; -const uint8_t HuffDecoderCommon::table1_144_emit_[59] = { - 0x74, 0x30, 0x30, 0x74, 0x30, 0x31, 0x74, 0x30, 0x32, 0x74, 0x30, 0x61, - 0x74, 0x30, 0x63, 0x74, 0x30, 0x65, 0x74, 0x30, 0x69, 0x74, 0x30, 0x6f, - 0x74, 0x30, 0x73, 0x74, 0x30, 0x74, 0x31, 0x30, 0x74, 0x31, 0x31, 0x74, - 0x31, 0x32, 0x74, 0x31, 0x61, 0x74, 0x31, 0x63, 0x74, 0x31, 0x65, 0x74, - 0x31, 0x69, 0x74, 0x31, 0x6f, 0x74, 0x31, 0x73, 0x74, 0x31, 0x74}; -const uint16_t HuffDecoderCommon::table1_144_inner_[22] = { - 0x000f, 0x00cf, 0x018f, 0x024f, 0x030f, 0x03cf, 0x048f, 0x054f, - 0x060f, 0x06cf, 0x001a, 0x074f, 0x080f, 0x08cf, 0x098f, 0x0a4f, - 0x0b0f, 0x0bcf, 0x0c8f, 0x0d4f, 0x0e0f, 0x075a}; -const uint8_t HuffDecoderCommon::table1_145_emit_[59] = { - 0x74, 0x32, 0x30, 0x74, 0x32, 0x31, 0x74, 0x32, 0x32, 0x74, 0x32, 0x61, - 0x74, 0x32, 0x63, 0x74, 0x32, 0x65, 0x74, 0x32, 0x69, 0x74, 0x32, 0x6f, - 0x74, 0x32, 0x73, 0x74, 0x32, 0x74, 0x61, 0x30, 0x74, 0x61, 0x31, 0x74, - 0x61, 0x32, 0x74, 0x61, 0x61, 0x74, 0x61, 0x63, 0x74, 0x61, 0x65, 0x74, - 0x61, 0x69, 0x74, 0x61, 0x6f, 0x74, 0x61, 0x73, 0x74, 0x61, 0x74}; -const uint8_t HuffDecoderCommon::table1_146_emit_[59] = { - 0x74, 0x63, 0x30, 0x74, 0x63, 0x31, 0x74, 0x63, 0x32, 0x74, 0x63, 0x61, - 0x74, 0x63, 0x63, 0x74, 0x63, 0x65, 0x74, 0x63, 0x69, 0x74, 0x63, 0x6f, - 0x74, 0x63, 0x73, 0x74, 0x63, 0x74, 0x65, 0x30, 0x74, 0x65, 0x31, 0x74, - 0x65, 0x32, 0x74, 0x65, 0x61, 0x74, 0x65, 0x63, 0x74, 0x65, 0x65, 0x74, - 0x65, 0x69, 0x74, 0x65, 0x6f, 0x74, 0x65, 0x73, 0x74, 0x65, 0x74}; -const uint8_t HuffDecoderCommon::table1_147_emit_[59] = { - 0x74, 0x69, 0x30, 0x74, 0x69, 0x31, 0x74, 0x69, 0x32, 0x74, 0x69, 0x61, - 0x74, 0x69, 0x63, 0x74, 0x69, 0x65, 0x74, 0x69, 0x69, 0x74, 0x69, 0x6f, - 0x74, 0x69, 0x73, 0x74, 0x69, 0x74, 0x6f, 0x30, 0x74, 0x6f, 0x31, 0x74, - 0x6f, 0x32, 0x74, 0x6f, 0x61, 0x74, 0x6f, 0x63, 0x74, 0x6f, 0x65, 0x74, - 0x6f, 0x69, 0x74, 0x6f, 0x6f, 0x74, 0x6f, 0x73, 0x74, 0x6f, 0x74}; -const uint8_t HuffDecoderCommon::table1_148_emit_[59] = { - 0x74, 0x73, 0x30, 0x74, 0x73, 0x31, 0x74, 0x73, 0x32, 0x74, 0x73, 0x61, - 0x74, 0x73, 0x63, 0x74, 0x73, 0x65, 0x74, 0x73, 0x69, 0x74, 0x73, 0x6f, - 0x74, 0x73, 0x73, 0x74, 0x73, 0x74, 0x74, 0x30, 0x74, 0x74, 0x31, 0x74, - 0x74, 0x32, 0x74, 0x74, 0x61, 0x74, 0x74, 0x63, 0x74, 0x74, 0x65, 0x74, - 0x74, 0x69, 0x74, 0x74, 0x6f, 0x74, 0x74, 0x73, 0x74, 0x74, 0x74}; -const uint8_t HuffDecoderCommon::table1_149_emit_[8] = {0x74, 0x20, 0x74, 0x25, - 0x74, 0x2d, 0x74, 0x2e}; -const uint8_t HuffDecoderCommon::table1_150_emit_[8] = {0x74, 0x2f, 0x74, 0x33, - 0x74, 0x34, 0x74, 0x35}; -const uint8_t HuffDecoderCommon::table1_151_emit_[8] = {0x74, 0x36, 0x74, 0x37, - 0x74, 0x38, 0x74, 0x39}; -const uint8_t HuffDecoderCommon::table1_152_emit_[8] = {0x74, 0x3d, 0x74, 0x41, - 0x74, 0x5f, 0x74, 0x62}; -const uint8_t HuffDecoderCommon::table1_153_emit_[8] = {0x74, 0x64, 0x74, 0x66, - 0x74, 0x67, 0x74, 0x68}; -const uint8_t HuffDecoderCommon::table1_154_emit_[8] = {0x74, 0x6c, 0x74, 0x6d, - 0x74, 0x6e, 0x74, 0x70}; -const uint8_t HuffDecoderCommon::table1_155_emit_[12] = { - 0x74, 0x72, 0x74, 0x75, 0x74, 0x3a, 0x74, 0x42, 0x74, 0x43, 0x74, 0x44}; -const uint8_t HuffDecoderCommon::table1_156_emit_[16] = { - 0x74, 0x45, 0x74, 0x46, 0x74, 0x47, 0x74, 0x48, - 0x74, 0x49, 0x74, 0x4a, 0x74, 0x4b, 0x74, 0x4c}; -const uint8_t HuffDecoderCommon::table1_157_emit_[16] = { - 0x74, 0x4d, 0x74, 0x4e, 0x74, 0x4f, 0x74, 0x50, - 0x74, 0x51, 0x74, 0x52, 0x74, 0x53, 0x74, 0x54}; -const uint8_t HuffDecoderCommon::table1_158_emit_[16] = { - 0x74, 0x55, 0x74, 0x56, 0x74, 0x57, 0x74, 0x59, - 0x74, 0x6a, 0x74, 0x6b, 0x74, 0x71, 0x74, 0x76}; -const uint8_t HuffDecoderCommon::table1_159_emit_[30] = { - 0x74, 0x77, 0x74, 0x78, 0x74, 0x79, 0x74, 0x7a, 0x74, 0x26, - 0x74, 0x2a, 0x74, 0x2c, 0x74, 0x3b, 0x74, 0x58, 0x74, 0x5a, - 0x74, 0x21, 0x74, 0x22, 0x74, 0x28, 0x74, 0x29, 0x74, 0x3f}; -const uint8_t HuffDecoderCommon::table1_160_emit_[8] = {0x20, 0x30, 0x20, 0x31, - 0x20, 0x32, 0x20, 0x61}; -const uint8_t HuffDecoderCommon::table1_161_emit_[8] = {0x20, 0x63, 0x20, 0x65, - 0x20, 0x69, 0x20, 0x6f}; -const uint8_t HuffDecoderCommon::table1_162_emit_[11] = { - 0x20, 0x73, 0x20, 0x74, 0x20, 0x20, 0x25, 0x20, 0x2d, 0x20, 0x2e}; -const uint16_t HuffDecoderCommon::table1_162_inner_[6] = { - 0x001b, 0x009b, 0x011c, 0x015c, 0x01dc, 0x025c}; -const uint8_t HuffDecoderCommon::table1_163_emit_[16] = { - 0x20, 0x2f, 0x20, 0x33, 0x20, 0x34, 0x20, 0x35, - 0x20, 0x36, 0x20, 0x37, 0x20, 0x38, 0x20, 0x39}; -const uint8_t HuffDecoderCommon::table1_164_emit_[16] = { - 0x20, 0x3d, 0x20, 0x41, 0x20, 0x5f, 0x20, 0x62, - 0x20, 0x64, 0x20, 0x66, 0x20, 0x67, 0x20, 0x68}; -const uint8_t HuffDecoderCommon::table1_165_emit_[20] = { - 0x20, 0x6c, 0x20, 0x6d, 0x20, 0x6e, 0x20, 0x70, 0x20, 0x72, - 0x20, 0x75, 0x20, 0x3a, 0x20, 0x42, 0x20, 0x43, 0x20, 0x44}; -const uint16_t HuffDecoderCommon::table1_165_inner_[10] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021c, - 0x029c, 0x031d, 0x039d, 0x041d, 0x049d}; -const uint8_t HuffDecoderCommon::table1_165_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, - 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9}; -const uint8_t HuffDecoderCommon::table1_166_emit_[32] = { - 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, 0x48, 0x20, 0x49, 0x20, - 0x4a, 0x20, 0x4b, 0x20, 0x4c, 0x20, 0x4d, 0x20, 0x4e, 0x20, 0x4f, - 0x20, 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, 0x54}; -const uint16_t HuffDecoderCommon::table1_166_inner_[16] = { - 0x001d, 0x009d, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, 0x039d, - 0x041d, 0x049d, 0x051d, 0x059d, 0x061d, 0x069d, 0x071d, 0x079d}; -const uint8_t HuffDecoderCommon::table1_166_outer_[64] = { - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, - 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15}; -const uint8_t HuffDecoderCommon::table1_167_emit_[36] = { - 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, 0x59, 0x20, 0x6a, 0x20, 0x6b, - 0x20, 0x71, 0x20, 0x76, 0x20, 0x77, 0x20, 0x78, 0x20, 0x79, 0x20, 0x7a, - 0x20, 0x26, 0x20, 0x2a, 0x20, 0x2c, 0x20, 0x3b, 0x20, 0x58, 0x20, 0x5a}; -const uint16_t HuffDecoderCommon::table1_167_inner_[19] = { - 0x001d, 0x009d, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, - 0x039d, 0x041d, 0x049d, 0x051d, 0x059d, 0x061e, 0x069e, - 0x071e, 0x079e, 0x081e, 0x089e, 0x0026}; -const uint8_t HuffDecoderCommon::table1_167_outer_[64] = { - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, - 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18}; -const uint8_t HuffDecoderCommon::table1_168_emit_[8] = {0x25, 0x30, 0x25, 0x31, - 0x25, 0x32, 0x25, 0x61}; -const uint8_t HuffDecoderCommon::table1_169_emit_[8] = {0x25, 0x63, 0x25, 0x65, - 0x25, 0x69, 0x25, 0x6f}; -const uint8_t HuffDecoderCommon::table1_170_emit_[11] = { - 0x25, 0x73, 0x25, 0x74, 0x25, 0x20, 0x25, 0x25, 0x2d, 0x25, 0x2e}; -const uint16_t HuffDecoderCommon::table1_170_inner_[6] = { - 0x001b, 0x009b, 0x011c, 0x019c, 0x01dc, 0x025c}; -const uint8_t HuffDecoderCommon::table1_171_emit_[16] = { - 0x25, 0x2f, 0x25, 0x33, 0x25, 0x34, 0x25, 0x35, - 0x25, 0x36, 0x25, 0x37, 0x25, 0x38, 0x25, 0x39}; -const uint8_t HuffDecoderCommon::table1_172_emit_[16] = { - 0x25, 0x3d, 0x25, 0x41, 0x25, 0x5f, 0x25, 0x62, - 0x25, 0x64, 0x25, 0x66, 0x25, 0x67, 0x25, 0x68}; -const uint8_t HuffDecoderCommon::table1_173_emit_[20] = { - 0x25, 0x6c, 0x25, 0x6d, 0x25, 0x6e, 0x25, 0x70, 0x25, 0x72, - 0x25, 0x75, 0x25, 0x3a, 0x25, 0x42, 0x25, 0x43, 0x25, 0x44}; -const uint8_t HuffDecoderCommon::table1_174_emit_[32] = { - 0x25, 0x45, 0x25, 0x46, 0x25, 0x47, 0x25, 0x48, 0x25, 0x49, 0x25, - 0x4a, 0x25, 0x4b, 0x25, 0x4c, 0x25, 0x4d, 0x25, 0x4e, 0x25, 0x4f, - 0x25, 0x50, 0x25, 0x51, 0x25, 0x52, 0x25, 0x53, 0x25, 0x54}; -const uint8_t HuffDecoderCommon::table1_175_emit_[36] = { - 0x25, 0x55, 0x25, 0x56, 0x25, 0x57, 0x25, 0x59, 0x25, 0x6a, 0x25, 0x6b, - 0x25, 0x71, 0x25, 0x76, 0x25, 0x77, 0x25, 0x78, 0x25, 0x79, 0x25, 0x7a, - 0x25, 0x26, 0x25, 0x2a, 0x25, 0x2c, 0x25, 0x3b, 0x25, 0x58, 0x25, 0x5a}; -const uint8_t HuffDecoderCommon::table1_176_emit_[8] = {0x2d, 0x30, 0x2d, 0x31, - 0x2d, 0x32, 0x2d, 0x61}; -const uint8_t HuffDecoderCommon::table1_177_emit_[8] = {0x2d, 0x63, 0x2d, 0x65, - 0x2d, 0x69, 0x2d, 0x6f}; -const uint8_t HuffDecoderCommon::table1_178_emit_[11] = { - 0x2d, 0x73, 0x2d, 0x74, 0x2d, 0x20, 0x2d, 0x25, 0x2d, 0x2d, 0x2e}; -const uint16_t HuffDecoderCommon::table1_178_inner_[6] = { - 0x001b, 0x009b, 0x011c, 0x019c, 0x021c, 0x025c}; -const uint8_t HuffDecoderCommon::table1_179_emit_[16] = { - 0x2d, 0x2f, 0x2d, 0x33, 0x2d, 0x34, 0x2d, 0x35, - 0x2d, 0x36, 0x2d, 0x37, 0x2d, 0x38, 0x2d, 0x39}; -const uint8_t HuffDecoderCommon::table1_180_emit_[16] = { - 0x2d, 0x3d, 0x2d, 0x41, 0x2d, 0x5f, 0x2d, 0x62, - 0x2d, 0x64, 0x2d, 0x66, 0x2d, 0x67, 0x2d, 0x68}; -const uint8_t HuffDecoderCommon::table1_181_emit_[20] = { - 0x2d, 0x6c, 0x2d, 0x6d, 0x2d, 0x6e, 0x2d, 0x70, 0x2d, 0x72, - 0x2d, 0x75, 0x2d, 0x3a, 0x2d, 0x42, 0x2d, 0x43, 0x2d, 0x44}; -const uint8_t HuffDecoderCommon::table1_182_emit_[32] = { - 0x2d, 0x45, 0x2d, 0x46, 0x2d, 0x47, 0x2d, 0x48, 0x2d, 0x49, 0x2d, - 0x4a, 0x2d, 0x4b, 0x2d, 0x4c, 0x2d, 0x4d, 0x2d, 0x4e, 0x2d, 0x4f, - 0x2d, 0x50, 0x2d, 0x51, 0x2d, 0x52, 0x2d, 0x53, 0x2d, 0x54}; -const uint8_t HuffDecoderCommon::table1_183_emit_[36] = { - 0x2d, 0x55, 0x2d, 0x56, 0x2d, 0x57, 0x2d, 0x59, 0x2d, 0x6a, 0x2d, 0x6b, - 0x2d, 0x71, 0x2d, 0x76, 0x2d, 0x77, 0x2d, 0x78, 0x2d, 0x79, 0x2d, 0x7a, - 0x2d, 0x26, 0x2d, 0x2a, 0x2d, 0x2c, 0x2d, 0x3b, 0x2d, 0x58, 0x2d, 0x5a}; -const uint8_t HuffDecoderCommon::table1_184_emit_[8] = {0x2e, 0x30, 0x2e, 0x31, - 0x2e, 0x32, 0x2e, 0x61}; -const uint8_t HuffDecoderCommon::table1_185_emit_[8] = {0x2e, 0x63, 0x2e, 0x65, - 0x2e, 0x69, 0x2e, 0x6f}; -const uint8_t HuffDecoderCommon::table1_186_emit_[12] = { - 0x2e, 0x73, 0x2e, 0x74, 0x2e, 0x20, 0x2e, 0x25, 0x2e, 0x2d, 0x2e, 0x2e}; -const uint8_t HuffDecoderCommon::table1_187_emit_[16] = { - 0x2e, 0x2f, 0x2e, 0x33, 0x2e, 0x34, 0x2e, 0x35, - 0x2e, 0x36, 0x2e, 0x37, 0x2e, 0x38, 0x2e, 0x39}; -const uint8_t HuffDecoderCommon::table1_188_emit_[16] = { - 0x2e, 0x3d, 0x2e, 0x41, 0x2e, 0x5f, 0x2e, 0x62, - 0x2e, 0x64, 0x2e, 0x66, 0x2e, 0x67, 0x2e, 0x68}; -const uint8_t HuffDecoderCommon::table1_189_emit_[20] = { - 0x2e, 0x6c, 0x2e, 0x6d, 0x2e, 0x6e, 0x2e, 0x70, 0x2e, 0x72, - 0x2e, 0x75, 0x2e, 0x3a, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x44}; -const uint8_t HuffDecoderCommon::table1_190_emit_[32] = { - 0x2e, 0x45, 0x2e, 0x46, 0x2e, 0x47, 0x2e, 0x48, 0x2e, 0x49, 0x2e, - 0x4a, 0x2e, 0x4b, 0x2e, 0x4c, 0x2e, 0x4d, 0x2e, 0x4e, 0x2e, 0x4f, - 0x2e, 0x50, 0x2e, 0x51, 0x2e, 0x52, 0x2e, 0x53, 0x2e, 0x54}; -const uint8_t HuffDecoderCommon::table1_191_emit_[36] = { - 0x2e, 0x55, 0x2e, 0x56, 0x2e, 0x57, 0x2e, 0x59, 0x2e, 0x6a, 0x2e, 0x6b, - 0x2e, 0x71, 0x2e, 0x76, 0x2e, 0x77, 0x2e, 0x78, 0x2e, 0x79, 0x2e, 0x7a, - 0x2e, 0x26, 0x2e, 0x2a, 0x2e, 0x2c, 0x2e, 0x3b, 0x2e, 0x58, 0x2e, 0x5a}; -const uint8_t HuffDecoderCommon::table1_192_emit_[8] = {0x2f, 0x30, 0x2f, 0x31, - 0x2f, 0x32, 0x2f, 0x61}; -const uint8_t HuffDecoderCommon::table1_193_emit_[8] = {0x2f, 0x63, 0x2f, 0x65, - 0x2f, 0x69, 0x2f, 0x6f}; -const uint8_t HuffDecoderCommon::table1_194_emit_[12] = { - 0x2f, 0x73, 0x2f, 0x74, 0x2f, 0x20, 0x2f, 0x25, 0x2f, 0x2d, 0x2f, 0x2e}; -const uint8_t HuffDecoderCommon::table1_195_emit_[15] = { - 0x2f, 0x2f, 0x33, 0x2f, 0x34, 0x2f, 0x35, 0x2f, - 0x36, 0x2f, 0x37, 0x2f, 0x38, 0x2f, 0x39}; -const uint16_t HuffDecoderCommon::table1_195_inner_[8] = { - 0x001c, 0x005c, 0x00dc, 0x015c, 0x01dc, 0x025c, 0x02dc, 0x035c}; -const uint8_t HuffDecoderCommon::table1_196_emit_[16] = { - 0x2f, 0x3d, 0x2f, 0x41, 0x2f, 0x5f, 0x2f, 0x62, - 0x2f, 0x64, 0x2f, 0x66, 0x2f, 0x67, 0x2f, 0x68}; -const uint8_t HuffDecoderCommon::table1_197_emit_[20] = { - 0x2f, 0x6c, 0x2f, 0x6d, 0x2f, 0x6e, 0x2f, 0x70, 0x2f, 0x72, - 0x2f, 0x75, 0x2f, 0x3a, 0x2f, 0x42, 0x2f, 0x43, 0x2f, 0x44}; -const uint8_t HuffDecoderCommon::table1_198_emit_[32] = { - 0x2f, 0x45, 0x2f, 0x46, 0x2f, 0x47, 0x2f, 0x48, 0x2f, 0x49, 0x2f, - 0x4a, 0x2f, 0x4b, 0x2f, 0x4c, 0x2f, 0x4d, 0x2f, 0x4e, 0x2f, 0x4f, - 0x2f, 0x50, 0x2f, 0x51, 0x2f, 0x52, 0x2f, 0x53, 0x2f, 0x54}; -const uint8_t HuffDecoderCommon::table1_199_emit_[36] = { - 0x2f, 0x55, 0x2f, 0x56, 0x2f, 0x57, 0x2f, 0x59, 0x2f, 0x6a, 0x2f, 0x6b, - 0x2f, 0x71, 0x2f, 0x76, 0x2f, 0x77, 0x2f, 0x78, 0x2f, 0x79, 0x2f, 0x7a, - 0x2f, 0x26, 0x2f, 0x2a, 0x2f, 0x2c, 0x2f, 0x3b, 0x2f, 0x58, 0x2f, 0x5a}; -const uint8_t HuffDecoderCommon::table1_200_emit_[8] = {0x33, 0x30, 0x33, 0x31, - 0x33, 0x32, 0x33, 0x61}; -const uint8_t HuffDecoderCommon::table1_201_emit_[8] = {0x33, 0x63, 0x33, 0x65, - 0x33, 0x69, 0x33, 0x6f}; -const uint8_t HuffDecoderCommon::table1_202_emit_[12] = { - 0x33, 0x73, 0x33, 0x74, 0x33, 0x20, 0x33, 0x25, 0x33, 0x2d, 0x33, 0x2e}; -const uint8_t HuffDecoderCommon::table1_203_emit_[15] = { - 0x33, 0x2f, 0x33, 0x33, 0x34, 0x33, 0x35, 0x33, - 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39}; -const uint16_t HuffDecoderCommon::table1_203_inner_[8] = { - 0x001c, 0x009c, 0x00dc, 0x015c, 0x01dc, 0x025c, 0x02dc, 0x035c}; -const uint8_t HuffDecoderCommon::table1_204_emit_[16] = { - 0x33, 0x3d, 0x33, 0x41, 0x33, 0x5f, 0x33, 0x62, - 0x33, 0x64, 0x33, 0x66, 0x33, 0x67, 0x33, 0x68}; -const uint8_t HuffDecoderCommon::table1_205_emit_[20] = { - 0x33, 0x6c, 0x33, 0x6d, 0x33, 0x6e, 0x33, 0x70, 0x33, 0x72, - 0x33, 0x75, 0x33, 0x3a, 0x33, 0x42, 0x33, 0x43, 0x33, 0x44}; -const uint8_t HuffDecoderCommon::table1_206_emit_[32] = { - 0x33, 0x45, 0x33, 0x46, 0x33, 0x47, 0x33, 0x48, 0x33, 0x49, 0x33, - 0x4a, 0x33, 0x4b, 0x33, 0x4c, 0x33, 0x4d, 0x33, 0x4e, 0x33, 0x4f, - 0x33, 0x50, 0x33, 0x51, 0x33, 0x52, 0x33, 0x53, 0x33, 0x54}; -const uint8_t HuffDecoderCommon::table1_207_emit_[36] = { - 0x33, 0x55, 0x33, 0x56, 0x33, 0x57, 0x33, 0x59, 0x33, 0x6a, 0x33, 0x6b, - 0x33, 0x71, 0x33, 0x76, 0x33, 0x77, 0x33, 0x78, 0x33, 0x79, 0x33, 0x7a, - 0x33, 0x26, 0x33, 0x2a, 0x33, 0x2c, 0x33, 0x3b, 0x33, 0x58, 0x33, 0x5a}; -const uint8_t HuffDecoderCommon::table1_208_emit_[8] = {0x34, 0x30, 0x34, 0x31, - 0x34, 0x32, 0x34, 0x61}; -const uint8_t HuffDecoderCommon::table1_209_emit_[8] = {0x34, 0x63, 0x34, 0x65, - 0x34, 0x69, 0x34, 0x6f}; -const uint8_t HuffDecoderCommon::table1_210_emit_[12] = { - 0x34, 0x73, 0x34, 0x74, 0x34, 0x20, 0x34, 0x25, 0x34, 0x2d, 0x34, 0x2e}; -const uint8_t HuffDecoderCommon::table1_211_emit_[15] = { - 0x34, 0x2f, 0x34, 0x33, 0x34, 0x34, 0x35, 0x34, - 0x36, 0x34, 0x37, 0x34, 0x38, 0x34, 0x39}; -const uint16_t HuffDecoderCommon::table1_211_inner_[8] = { - 0x001c, 0x009c, 0x011c, 0x015c, 0x01dc, 0x025c, 0x02dc, 0x035c}; -const uint8_t HuffDecoderCommon::table1_212_emit_[16] = { - 0x34, 0x3d, 0x34, 0x41, 0x34, 0x5f, 0x34, 0x62, - 0x34, 0x64, 0x34, 0x66, 0x34, 0x67, 0x34, 0x68}; -const uint8_t HuffDecoderCommon::table1_213_emit_[20] = { - 0x34, 0x6c, 0x34, 0x6d, 0x34, 0x6e, 0x34, 0x70, 0x34, 0x72, - 0x34, 0x75, 0x34, 0x3a, 0x34, 0x42, 0x34, 0x43, 0x34, 0x44}; -const uint8_t HuffDecoderCommon::table1_214_emit_[32] = { - 0x34, 0x45, 0x34, 0x46, 0x34, 0x47, 0x34, 0x48, 0x34, 0x49, 0x34, - 0x4a, 0x34, 0x4b, 0x34, 0x4c, 0x34, 0x4d, 0x34, 0x4e, 0x34, 0x4f, - 0x34, 0x50, 0x34, 0x51, 0x34, 0x52, 0x34, 0x53, 0x34, 0x54}; -const uint8_t HuffDecoderCommon::table1_215_emit_[36] = { - 0x34, 0x55, 0x34, 0x56, 0x34, 0x57, 0x34, 0x59, 0x34, 0x6a, 0x34, 0x6b, - 0x34, 0x71, 0x34, 0x76, 0x34, 0x77, 0x34, 0x78, 0x34, 0x79, 0x34, 0x7a, - 0x34, 0x26, 0x34, 0x2a, 0x34, 0x2c, 0x34, 0x3b, 0x34, 0x58, 0x34, 0x5a}; -const uint8_t HuffDecoderCommon::table1_216_emit_[8] = {0x35, 0x30, 0x35, 0x31, - 0x35, 0x32, 0x35, 0x61}; -const uint8_t HuffDecoderCommon::table1_217_emit_[8] = {0x35, 0x63, 0x35, 0x65, - 0x35, 0x69, 0x35, 0x6f}; -const uint8_t HuffDecoderCommon::table1_218_emit_[12] = { - 0x35, 0x73, 0x35, 0x74, 0x35, 0x20, 0x35, 0x25, 0x35, 0x2d, 0x35, 0x2e}; -const uint8_t HuffDecoderCommon::table1_219_emit_[15] = { - 0x35, 0x2f, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, - 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39}; -const uint16_t HuffDecoderCommon::table1_219_inner_[8] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x01dc, 0x025c, 0x02dc, 0x035c}; -const uint8_t HuffDecoderCommon::table1_220_emit_[16] = { - 0x35, 0x3d, 0x35, 0x41, 0x35, 0x5f, 0x35, 0x62, - 0x35, 0x64, 0x35, 0x66, 0x35, 0x67, 0x35, 0x68}; -const uint8_t HuffDecoderCommon::table1_221_emit_[20] = { - 0x35, 0x6c, 0x35, 0x6d, 0x35, 0x6e, 0x35, 0x70, 0x35, 0x72, - 0x35, 0x75, 0x35, 0x3a, 0x35, 0x42, 0x35, 0x43, 0x35, 0x44}; -const uint8_t HuffDecoderCommon::table1_222_emit_[32] = { - 0x35, 0x45, 0x35, 0x46, 0x35, 0x47, 0x35, 0x48, 0x35, 0x49, 0x35, - 0x4a, 0x35, 0x4b, 0x35, 0x4c, 0x35, 0x4d, 0x35, 0x4e, 0x35, 0x4f, - 0x35, 0x50, 0x35, 0x51, 0x35, 0x52, 0x35, 0x53, 0x35, 0x54}; -const uint8_t HuffDecoderCommon::table1_223_emit_[36] = { - 0x35, 0x55, 0x35, 0x56, 0x35, 0x57, 0x35, 0x59, 0x35, 0x6a, 0x35, 0x6b, - 0x35, 0x71, 0x35, 0x76, 0x35, 0x77, 0x35, 0x78, 0x35, 0x79, 0x35, 0x7a, - 0x35, 0x26, 0x35, 0x2a, 0x35, 0x2c, 0x35, 0x3b, 0x35, 0x58, 0x35, 0x5a}; -const uint8_t HuffDecoderCommon::table1_224_emit_[8] = {0x36, 0x30, 0x36, 0x31, - 0x36, 0x32, 0x36, 0x61}; -const uint8_t HuffDecoderCommon::table1_225_emit_[8] = {0x36, 0x63, 0x36, 0x65, - 0x36, 0x69, 0x36, 0x6f}; -const uint8_t HuffDecoderCommon::table1_226_emit_[12] = { - 0x36, 0x73, 0x36, 0x74, 0x36, 0x20, 0x36, 0x25, 0x36, 0x2d, 0x36, 0x2e}; -const uint8_t HuffDecoderCommon::table1_227_emit_[15] = { - 0x36, 0x2f, 0x36, 0x33, 0x36, 0x34, 0x36, 0x35, - 0x36, 0x36, 0x37, 0x36, 0x38, 0x36, 0x39}; -const uint16_t HuffDecoderCommon::table1_227_inner_[8] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021c, 0x025c, 0x02dc, 0x035c}; -const uint8_t HuffDecoderCommon::table1_228_emit_[16] = { - 0x36, 0x3d, 0x36, 0x41, 0x36, 0x5f, 0x36, 0x62, - 0x36, 0x64, 0x36, 0x66, 0x36, 0x67, 0x36, 0x68}; -const uint8_t HuffDecoderCommon::table1_229_emit_[20] = { - 0x36, 0x6c, 0x36, 0x6d, 0x36, 0x6e, 0x36, 0x70, 0x36, 0x72, - 0x36, 0x75, 0x36, 0x3a, 0x36, 0x42, 0x36, 0x43, 0x36, 0x44}; -const uint8_t HuffDecoderCommon::table1_230_emit_[32] = { - 0x36, 0x45, 0x36, 0x46, 0x36, 0x47, 0x36, 0x48, 0x36, 0x49, 0x36, - 0x4a, 0x36, 0x4b, 0x36, 0x4c, 0x36, 0x4d, 0x36, 0x4e, 0x36, 0x4f, - 0x36, 0x50, 0x36, 0x51, 0x36, 0x52, 0x36, 0x53, 0x36, 0x54}; -const uint8_t HuffDecoderCommon::table1_231_emit_[36] = { - 0x36, 0x55, 0x36, 0x56, 0x36, 0x57, 0x36, 0x59, 0x36, 0x6a, 0x36, 0x6b, - 0x36, 0x71, 0x36, 0x76, 0x36, 0x77, 0x36, 0x78, 0x36, 0x79, 0x36, 0x7a, - 0x36, 0x26, 0x36, 0x2a, 0x36, 0x2c, 0x36, 0x3b, 0x36, 0x58, 0x36, 0x5a}; -const uint8_t HuffDecoderCommon::table1_232_emit_[8] = {0x37, 0x30, 0x37, 0x31, - 0x37, 0x32, 0x37, 0x61}; -const uint8_t HuffDecoderCommon::table1_233_emit_[8] = {0x37, 0x63, 0x37, 0x65, - 0x37, 0x69, 0x37, 0x6f}; -const uint8_t HuffDecoderCommon::table1_234_emit_[12] = { - 0x37, 0x73, 0x37, 0x74, 0x37, 0x20, 0x37, 0x25, 0x37, 0x2d, 0x37, 0x2e}; -const uint8_t HuffDecoderCommon::table1_235_emit_[15] = { - 0x37, 0x2f, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, - 0x37, 0x36, 0x37, 0x37, 0x38, 0x37, 0x39}; -const uint16_t HuffDecoderCommon::table1_235_inner_[8] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021c, 0x029c, 0x02dc, 0x035c}; -const uint8_t HuffDecoderCommon::table1_236_emit_[16] = { - 0x37, 0x3d, 0x37, 0x41, 0x37, 0x5f, 0x37, 0x62, - 0x37, 0x64, 0x37, 0x66, 0x37, 0x67, 0x37, 0x68}; -const uint8_t HuffDecoderCommon::table1_237_emit_[20] = { - 0x37, 0x6c, 0x37, 0x6d, 0x37, 0x6e, 0x37, 0x70, 0x37, 0x72, - 0x37, 0x75, 0x37, 0x3a, 0x37, 0x42, 0x37, 0x43, 0x37, 0x44}; -const uint8_t HuffDecoderCommon::table1_238_emit_[32] = { - 0x37, 0x45, 0x37, 0x46, 0x37, 0x47, 0x37, 0x48, 0x37, 0x49, 0x37, - 0x4a, 0x37, 0x4b, 0x37, 0x4c, 0x37, 0x4d, 0x37, 0x4e, 0x37, 0x4f, - 0x37, 0x50, 0x37, 0x51, 0x37, 0x52, 0x37, 0x53, 0x37, 0x54}; -const uint8_t HuffDecoderCommon::table1_239_emit_[36] = { - 0x37, 0x55, 0x37, 0x56, 0x37, 0x57, 0x37, 0x59, 0x37, 0x6a, 0x37, 0x6b, - 0x37, 0x71, 0x37, 0x76, 0x37, 0x77, 0x37, 0x78, 0x37, 0x79, 0x37, 0x7a, - 0x37, 0x26, 0x37, 0x2a, 0x37, 0x2c, 0x37, 0x3b, 0x37, 0x58, 0x37, 0x5a}; -const uint8_t HuffDecoderCommon::table1_240_emit_[8] = {0x38, 0x30, 0x38, 0x31, - 0x38, 0x32, 0x38, 0x61}; -const uint8_t HuffDecoderCommon::table1_241_emit_[8] = {0x38, 0x63, 0x38, 0x65, - 0x38, 0x69, 0x38, 0x6f}; -const uint8_t HuffDecoderCommon::table1_242_emit_[12] = { - 0x38, 0x73, 0x38, 0x74, 0x38, 0x20, 0x38, 0x25, 0x38, 0x2d, 0x38, 0x2e}; -const uint8_t HuffDecoderCommon::table1_243_emit_[15] = { - 0x38, 0x2f, 0x38, 0x33, 0x38, 0x34, 0x38, 0x35, - 0x38, 0x36, 0x38, 0x37, 0x38, 0x38, 0x39}; -const uint16_t HuffDecoderCommon::table1_243_inner_[8] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021c, 0x029c, 0x031c, 0x035c}; -const uint8_t HuffDecoderCommon::table1_244_emit_[16] = { - 0x38, 0x3d, 0x38, 0x41, 0x38, 0x5f, 0x38, 0x62, - 0x38, 0x64, 0x38, 0x66, 0x38, 0x67, 0x38, 0x68}; -const uint8_t HuffDecoderCommon::table1_245_emit_[20] = { - 0x38, 0x6c, 0x38, 0x6d, 0x38, 0x6e, 0x38, 0x70, 0x38, 0x72, - 0x38, 0x75, 0x38, 0x3a, 0x38, 0x42, 0x38, 0x43, 0x38, 0x44}; -const uint8_t HuffDecoderCommon::table1_246_emit_[32] = { - 0x38, 0x45, 0x38, 0x46, 0x38, 0x47, 0x38, 0x48, 0x38, 0x49, 0x38, - 0x4a, 0x38, 0x4b, 0x38, 0x4c, 0x38, 0x4d, 0x38, 0x4e, 0x38, 0x4f, - 0x38, 0x50, 0x38, 0x51, 0x38, 0x52, 0x38, 0x53, 0x38, 0x54}; -const uint8_t HuffDecoderCommon::table1_247_emit_[36] = { - 0x38, 0x55, 0x38, 0x56, 0x38, 0x57, 0x38, 0x59, 0x38, 0x6a, 0x38, 0x6b, - 0x38, 0x71, 0x38, 0x76, 0x38, 0x77, 0x38, 0x78, 0x38, 0x79, 0x38, 0x7a, - 0x38, 0x26, 0x38, 0x2a, 0x38, 0x2c, 0x38, 0x3b, 0x38, 0x58, 0x38, 0x5a}; -const uint8_t HuffDecoderCommon::table1_248_emit_[8] = {0x39, 0x30, 0x39, 0x31, - 0x39, 0x32, 0x39, 0x61}; -const uint8_t HuffDecoderCommon::table1_249_emit_[8] = {0x39, 0x63, 0x39, 0x65, - 0x39, 0x69, 0x39, 0x6f}; -const uint8_t HuffDecoderCommon::table1_250_emit_[12] = { - 0x39, 0x73, 0x39, 0x74, 0x39, 0x20, 0x39, 0x25, 0x39, 0x2d, 0x39, 0x2e}; -const uint8_t HuffDecoderCommon::table1_251_emit_[16] = { - 0x39, 0x2f, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, - 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39}; -const uint8_t HuffDecoderCommon::table1_252_emit_[16] = { - 0x39, 0x3d, 0x39, 0x41, 0x39, 0x5f, 0x39, 0x62, - 0x39, 0x64, 0x39, 0x66, 0x39, 0x67, 0x39, 0x68}; -const uint8_t HuffDecoderCommon::table1_253_emit_[20] = { - 0x39, 0x6c, 0x39, 0x6d, 0x39, 0x6e, 0x39, 0x70, 0x39, 0x72, - 0x39, 0x75, 0x39, 0x3a, 0x39, 0x42, 0x39, 0x43, 0x39, 0x44}; -const uint8_t HuffDecoderCommon::table1_254_emit_[32] = { - 0x39, 0x45, 0x39, 0x46, 0x39, 0x47, 0x39, 0x48, 0x39, 0x49, 0x39, - 0x4a, 0x39, 0x4b, 0x39, 0x4c, 0x39, 0x4d, 0x39, 0x4e, 0x39, 0x4f, - 0x39, 0x50, 0x39, 0x51, 0x39, 0x52, 0x39, 0x53, 0x39, 0x54}; -const uint8_t HuffDecoderCommon::table1_255_emit_[36] = { - 0x39, 0x55, 0x39, 0x56, 0x39, 0x57, 0x39, 0x59, 0x39, 0x6a, 0x39, 0x6b, - 0x39, 0x71, 0x39, 0x76, 0x39, 0x77, 0x39, 0x78, 0x39, 0x79, 0x39, 0x7a, - 0x39, 0x26, 0x39, 0x2a, 0x39, 0x2c, 0x39, 0x3b, 0x39, 0x58, 0x39, 0x5a}; -const uint8_t HuffDecoderCommon::table1_256_emit_[8] = {0x3d, 0x30, 0x3d, 0x31, - 0x3d, 0x32, 0x3d, 0x61}; -const uint8_t HuffDecoderCommon::table1_257_emit_[8] = {0x3d, 0x63, 0x3d, 0x65, - 0x3d, 0x69, 0x3d, 0x6f}; -const uint8_t HuffDecoderCommon::table1_258_emit_[12] = { - 0x3d, 0x73, 0x3d, 0x74, 0x3d, 0x20, 0x3d, 0x25, 0x3d, 0x2d, 0x3d, 0x2e}; -const uint8_t HuffDecoderCommon::table1_259_emit_[16] = { - 0x3d, 0x2f, 0x3d, 0x33, 0x3d, 0x34, 0x3d, 0x35, - 0x3d, 0x36, 0x3d, 0x37, 0x3d, 0x38, 0x3d, 0x39}; -const uint8_t HuffDecoderCommon::table1_260_emit_[15] = { - 0x3d, 0x3d, 0x41, 0x3d, 0x5f, 0x3d, 0x62, 0x3d, - 0x64, 0x3d, 0x66, 0x3d, 0x67, 0x3d, 0x68}; -const uint8_t HuffDecoderCommon::table1_261_emit_[20] = { - 0x3d, 0x6c, 0x3d, 0x6d, 0x3d, 0x6e, 0x3d, 0x70, 0x3d, 0x72, - 0x3d, 0x75, 0x3d, 0x3a, 0x3d, 0x42, 0x3d, 0x43, 0x3d, 0x44}; -const uint8_t HuffDecoderCommon::table1_262_emit_[32] = { - 0x3d, 0x45, 0x3d, 0x46, 0x3d, 0x47, 0x3d, 0x48, 0x3d, 0x49, 0x3d, - 0x4a, 0x3d, 0x4b, 0x3d, 0x4c, 0x3d, 0x4d, 0x3d, 0x4e, 0x3d, 0x4f, - 0x3d, 0x50, 0x3d, 0x51, 0x3d, 0x52, 0x3d, 0x53, 0x3d, 0x54}; -const uint8_t HuffDecoderCommon::table1_263_emit_[36] = { - 0x3d, 0x55, 0x3d, 0x56, 0x3d, 0x57, 0x3d, 0x59, 0x3d, 0x6a, 0x3d, 0x6b, - 0x3d, 0x71, 0x3d, 0x76, 0x3d, 0x77, 0x3d, 0x78, 0x3d, 0x79, 0x3d, 0x7a, - 0x3d, 0x26, 0x3d, 0x2a, 0x3d, 0x2c, 0x3d, 0x3b, 0x3d, 0x58, 0x3d, 0x5a}; -const uint8_t HuffDecoderCommon::table1_264_emit_[8] = {0x41, 0x30, 0x41, 0x31, - 0x41, 0x32, 0x41, 0x61}; -const uint8_t HuffDecoderCommon::table1_265_emit_[8] = {0x41, 0x63, 0x41, 0x65, - 0x41, 0x69, 0x41, 0x6f}; -const uint8_t HuffDecoderCommon::table1_266_emit_[12] = { - 0x41, 0x73, 0x41, 0x74, 0x41, 0x20, 0x41, 0x25, 0x41, 0x2d, 0x41, 0x2e}; -const uint8_t HuffDecoderCommon::table1_267_emit_[16] = { - 0x41, 0x2f, 0x41, 0x33, 0x41, 0x34, 0x41, 0x35, - 0x41, 0x36, 0x41, 0x37, 0x41, 0x38, 0x41, 0x39}; -const uint8_t HuffDecoderCommon::table1_268_emit_[15] = { - 0x41, 0x3d, 0x41, 0x41, 0x5f, 0x41, 0x62, 0x41, - 0x64, 0x41, 0x66, 0x41, 0x67, 0x41, 0x68}; -const uint8_t HuffDecoderCommon::table1_269_emit_[20] = { - 0x41, 0x6c, 0x41, 0x6d, 0x41, 0x6e, 0x41, 0x70, 0x41, 0x72, - 0x41, 0x75, 0x41, 0x3a, 0x41, 0x42, 0x41, 0x43, 0x41, 0x44}; -const uint8_t HuffDecoderCommon::table1_270_emit_[32] = { - 0x41, 0x45, 0x41, 0x46, 0x41, 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, - 0x4a, 0x41, 0x4b, 0x41, 0x4c, 0x41, 0x4d, 0x41, 0x4e, 0x41, 0x4f, - 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54}; -const uint8_t HuffDecoderCommon::table1_271_emit_[36] = { - 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x41, 0x59, 0x41, 0x6a, 0x41, 0x6b, - 0x41, 0x71, 0x41, 0x76, 0x41, 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7a, - 0x41, 0x26, 0x41, 0x2a, 0x41, 0x2c, 0x41, 0x3b, 0x41, 0x58, 0x41, 0x5a}; -const uint8_t HuffDecoderCommon::table1_272_emit_[8] = {0x5f, 0x30, 0x5f, 0x31, - 0x5f, 0x32, 0x5f, 0x61}; -const uint8_t HuffDecoderCommon::table1_273_emit_[8] = {0x5f, 0x63, 0x5f, 0x65, - 0x5f, 0x69, 0x5f, 0x6f}; -const uint8_t HuffDecoderCommon::table1_274_emit_[12] = { - 0x5f, 0x73, 0x5f, 0x74, 0x5f, 0x20, 0x5f, 0x25, 0x5f, 0x2d, 0x5f, 0x2e}; -const uint8_t HuffDecoderCommon::table1_275_emit_[16] = { - 0x5f, 0x2f, 0x5f, 0x33, 0x5f, 0x34, 0x5f, 0x35, - 0x5f, 0x36, 0x5f, 0x37, 0x5f, 0x38, 0x5f, 0x39}; -const uint8_t HuffDecoderCommon::table1_276_emit_[15] = { - 0x5f, 0x3d, 0x5f, 0x41, 0x5f, 0x5f, 0x62, 0x5f, - 0x64, 0x5f, 0x66, 0x5f, 0x67, 0x5f, 0x68}; -const uint8_t HuffDecoderCommon::table1_277_emit_[20] = { - 0x5f, 0x6c, 0x5f, 0x6d, 0x5f, 0x6e, 0x5f, 0x70, 0x5f, 0x72, - 0x5f, 0x75, 0x5f, 0x3a, 0x5f, 0x42, 0x5f, 0x43, 0x5f, 0x44}; -const uint8_t HuffDecoderCommon::table1_278_emit_[32] = { - 0x5f, 0x45, 0x5f, 0x46, 0x5f, 0x47, 0x5f, 0x48, 0x5f, 0x49, 0x5f, - 0x4a, 0x5f, 0x4b, 0x5f, 0x4c, 0x5f, 0x4d, 0x5f, 0x4e, 0x5f, 0x4f, - 0x5f, 0x50, 0x5f, 0x51, 0x5f, 0x52, 0x5f, 0x53, 0x5f, 0x54}; -const uint8_t HuffDecoderCommon::table1_279_emit_[36] = { - 0x5f, 0x55, 0x5f, 0x56, 0x5f, 0x57, 0x5f, 0x59, 0x5f, 0x6a, 0x5f, 0x6b, - 0x5f, 0x71, 0x5f, 0x76, 0x5f, 0x77, 0x5f, 0x78, 0x5f, 0x79, 0x5f, 0x7a, - 0x5f, 0x26, 0x5f, 0x2a, 0x5f, 0x2c, 0x5f, 0x3b, 0x5f, 0x58, 0x5f, 0x5a}; -const uint8_t HuffDecoderCommon::table1_280_emit_[8] = {0x62, 0x30, 0x62, 0x31, - 0x62, 0x32, 0x62, 0x61}; -const uint8_t HuffDecoderCommon::table1_281_emit_[8] = {0x62, 0x63, 0x62, 0x65, - 0x62, 0x69, 0x62, 0x6f}; -const uint8_t HuffDecoderCommon::table1_282_emit_[12] = { - 0x62, 0x73, 0x62, 0x74, 0x62, 0x20, 0x62, 0x25, 0x62, 0x2d, 0x62, 0x2e}; -const uint8_t HuffDecoderCommon::table1_283_emit_[16] = { - 0x62, 0x2f, 0x62, 0x33, 0x62, 0x34, 0x62, 0x35, - 0x62, 0x36, 0x62, 0x37, 0x62, 0x38, 0x62, 0x39}; -const uint8_t HuffDecoderCommon::table1_284_emit_[15] = { - 0x62, 0x3d, 0x62, 0x41, 0x62, 0x5f, 0x62, 0x62, - 0x64, 0x62, 0x66, 0x62, 0x67, 0x62, 0x68}; -const uint8_t HuffDecoderCommon::table1_285_emit_[20] = { - 0x62, 0x6c, 0x62, 0x6d, 0x62, 0x6e, 0x62, 0x70, 0x62, 0x72, - 0x62, 0x75, 0x62, 0x3a, 0x62, 0x42, 0x62, 0x43, 0x62, 0x44}; -const uint8_t HuffDecoderCommon::table1_286_emit_[32] = { - 0x62, 0x45, 0x62, 0x46, 0x62, 0x47, 0x62, 0x48, 0x62, 0x49, 0x62, - 0x4a, 0x62, 0x4b, 0x62, 0x4c, 0x62, 0x4d, 0x62, 0x4e, 0x62, 0x4f, - 0x62, 0x50, 0x62, 0x51, 0x62, 0x52, 0x62, 0x53, 0x62, 0x54}; -const uint8_t HuffDecoderCommon::table1_287_emit_[36] = { - 0x62, 0x55, 0x62, 0x56, 0x62, 0x57, 0x62, 0x59, 0x62, 0x6a, 0x62, 0x6b, - 0x62, 0x71, 0x62, 0x76, 0x62, 0x77, 0x62, 0x78, 0x62, 0x79, 0x62, 0x7a, - 0x62, 0x26, 0x62, 0x2a, 0x62, 0x2c, 0x62, 0x3b, 0x62, 0x58, 0x62, 0x5a}; -const uint8_t HuffDecoderCommon::table1_288_emit_[8] = {0x64, 0x30, 0x64, 0x31, - 0x64, 0x32, 0x64, 0x61}; -const uint8_t HuffDecoderCommon::table1_289_emit_[8] = {0x64, 0x63, 0x64, 0x65, - 0x64, 0x69, 0x64, 0x6f}; -const uint8_t HuffDecoderCommon::table1_290_emit_[12] = { - 0x64, 0x73, 0x64, 0x74, 0x64, 0x20, 0x64, 0x25, 0x64, 0x2d, 0x64, 0x2e}; -const uint8_t HuffDecoderCommon::table1_291_emit_[16] = { - 0x64, 0x2f, 0x64, 0x33, 0x64, 0x34, 0x64, 0x35, - 0x64, 0x36, 0x64, 0x37, 0x64, 0x38, 0x64, 0x39}; -const uint8_t HuffDecoderCommon::table1_292_emit_[15] = { - 0x64, 0x3d, 0x64, 0x41, 0x64, 0x5f, 0x64, 0x62, - 0x64, 0x64, 0x66, 0x64, 0x67, 0x64, 0x68}; -const uint8_t HuffDecoderCommon::table1_293_emit_[20] = { - 0x64, 0x6c, 0x64, 0x6d, 0x64, 0x6e, 0x64, 0x70, 0x64, 0x72, - 0x64, 0x75, 0x64, 0x3a, 0x64, 0x42, 0x64, 0x43, 0x64, 0x44}; -const uint8_t HuffDecoderCommon::table1_294_emit_[32] = { - 0x64, 0x45, 0x64, 0x46, 0x64, 0x47, 0x64, 0x48, 0x64, 0x49, 0x64, - 0x4a, 0x64, 0x4b, 0x64, 0x4c, 0x64, 0x4d, 0x64, 0x4e, 0x64, 0x4f, - 0x64, 0x50, 0x64, 0x51, 0x64, 0x52, 0x64, 0x53, 0x64, 0x54}; -const uint8_t HuffDecoderCommon::table1_295_emit_[36] = { - 0x64, 0x55, 0x64, 0x56, 0x64, 0x57, 0x64, 0x59, 0x64, 0x6a, 0x64, 0x6b, - 0x64, 0x71, 0x64, 0x76, 0x64, 0x77, 0x64, 0x78, 0x64, 0x79, 0x64, 0x7a, - 0x64, 0x26, 0x64, 0x2a, 0x64, 0x2c, 0x64, 0x3b, 0x64, 0x58, 0x64, 0x5a}; -const uint8_t HuffDecoderCommon::table1_296_emit_[8] = {0x66, 0x30, 0x66, 0x31, - 0x66, 0x32, 0x66, 0x61}; -const uint8_t HuffDecoderCommon::table1_297_emit_[8] = {0x66, 0x63, 0x66, 0x65, - 0x66, 0x69, 0x66, 0x6f}; -const uint8_t HuffDecoderCommon::table1_298_emit_[12] = { - 0x66, 0x73, 0x66, 0x74, 0x66, 0x20, 0x66, 0x25, 0x66, 0x2d, 0x66, 0x2e}; -const uint8_t HuffDecoderCommon::table1_299_emit_[16] = { - 0x66, 0x2f, 0x66, 0x33, 0x66, 0x34, 0x66, 0x35, - 0x66, 0x36, 0x66, 0x37, 0x66, 0x38, 0x66, 0x39}; -const uint8_t HuffDecoderCommon::table1_300_emit_[15] = { - 0x66, 0x3d, 0x66, 0x41, 0x66, 0x5f, 0x66, 0x62, - 0x66, 0x64, 0x66, 0x66, 0x67, 0x66, 0x68}; -const uint8_t HuffDecoderCommon::table1_301_emit_[20] = { - 0x66, 0x6c, 0x66, 0x6d, 0x66, 0x6e, 0x66, 0x70, 0x66, 0x72, - 0x66, 0x75, 0x66, 0x3a, 0x66, 0x42, 0x66, 0x43, 0x66, 0x44}; -const uint8_t HuffDecoderCommon::table1_302_emit_[32] = { - 0x66, 0x45, 0x66, 0x46, 0x66, 0x47, 0x66, 0x48, 0x66, 0x49, 0x66, - 0x4a, 0x66, 0x4b, 0x66, 0x4c, 0x66, 0x4d, 0x66, 0x4e, 0x66, 0x4f, - 0x66, 0x50, 0x66, 0x51, 0x66, 0x52, 0x66, 0x53, 0x66, 0x54}; -const uint8_t HuffDecoderCommon::table1_303_emit_[36] = { - 0x66, 0x55, 0x66, 0x56, 0x66, 0x57, 0x66, 0x59, 0x66, 0x6a, 0x66, 0x6b, - 0x66, 0x71, 0x66, 0x76, 0x66, 0x77, 0x66, 0x78, 0x66, 0x79, 0x66, 0x7a, - 0x66, 0x26, 0x66, 0x2a, 0x66, 0x2c, 0x66, 0x3b, 0x66, 0x58, 0x66, 0x5a}; -const uint8_t HuffDecoderCommon::table1_304_emit_[8] = {0x67, 0x30, 0x67, 0x31, - 0x67, 0x32, 0x67, 0x61}; -const uint8_t HuffDecoderCommon::table1_305_emit_[8] = {0x67, 0x63, 0x67, 0x65, - 0x67, 0x69, 0x67, 0x6f}; -const uint8_t HuffDecoderCommon::table1_306_emit_[12] = { - 0x67, 0x73, 0x67, 0x74, 0x67, 0x20, 0x67, 0x25, 0x67, 0x2d, 0x67, 0x2e}; -const uint8_t HuffDecoderCommon::table1_307_emit_[16] = { - 0x67, 0x2f, 0x67, 0x33, 0x67, 0x34, 0x67, 0x35, - 0x67, 0x36, 0x67, 0x37, 0x67, 0x38, 0x67, 0x39}; -const uint8_t HuffDecoderCommon::table1_308_emit_[15] = { - 0x67, 0x3d, 0x67, 0x41, 0x67, 0x5f, 0x67, 0x62, - 0x67, 0x64, 0x67, 0x66, 0x67, 0x67, 0x68}; -const uint8_t HuffDecoderCommon::table1_309_emit_[20] = { - 0x67, 0x6c, 0x67, 0x6d, 0x67, 0x6e, 0x67, 0x70, 0x67, 0x72, - 0x67, 0x75, 0x67, 0x3a, 0x67, 0x42, 0x67, 0x43, 0x67, 0x44}; -const uint8_t HuffDecoderCommon::table1_310_emit_[32] = { - 0x67, 0x45, 0x67, 0x46, 0x67, 0x47, 0x67, 0x48, 0x67, 0x49, 0x67, - 0x4a, 0x67, 0x4b, 0x67, 0x4c, 0x67, 0x4d, 0x67, 0x4e, 0x67, 0x4f, - 0x67, 0x50, 0x67, 0x51, 0x67, 0x52, 0x67, 0x53, 0x67, 0x54}; -const uint8_t HuffDecoderCommon::table1_311_emit_[36] = { - 0x67, 0x55, 0x67, 0x56, 0x67, 0x57, 0x67, 0x59, 0x67, 0x6a, 0x67, 0x6b, - 0x67, 0x71, 0x67, 0x76, 0x67, 0x77, 0x67, 0x78, 0x67, 0x79, 0x67, 0x7a, - 0x67, 0x26, 0x67, 0x2a, 0x67, 0x2c, 0x67, 0x3b, 0x67, 0x58, 0x67, 0x5a}; -const uint8_t HuffDecoderCommon::table1_312_emit_[8] = {0x68, 0x30, 0x68, 0x31, - 0x68, 0x32, 0x68, 0x61}; -const uint8_t HuffDecoderCommon::table1_313_emit_[8] = {0x68, 0x63, 0x68, 0x65, - 0x68, 0x69, 0x68, 0x6f}; -const uint8_t HuffDecoderCommon::table1_314_emit_[12] = { - 0x68, 0x73, 0x68, 0x74, 0x68, 0x20, 0x68, 0x25, 0x68, 0x2d, 0x68, 0x2e}; -const uint8_t HuffDecoderCommon::table1_315_emit_[16] = { - 0x68, 0x2f, 0x68, 0x33, 0x68, 0x34, 0x68, 0x35, - 0x68, 0x36, 0x68, 0x37, 0x68, 0x38, 0x68, 0x39}; -const uint8_t HuffDecoderCommon::table1_316_emit_[16] = { - 0x68, 0x3d, 0x68, 0x41, 0x68, 0x5f, 0x68, 0x62, - 0x68, 0x64, 0x68, 0x66, 0x68, 0x67, 0x68, 0x68}; -const uint8_t HuffDecoderCommon::table1_317_emit_[20] = { - 0x68, 0x6c, 0x68, 0x6d, 0x68, 0x6e, 0x68, 0x70, 0x68, 0x72, - 0x68, 0x75, 0x68, 0x3a, 0x68, 0x42, 0x68, 0x43, 0x68, 0x44}; -const uint8_t HuffDecoderCommon::table1_318_emit_[32] = { - 0x68, 0x45, 0x68, 0x46, 0x68, 0x47, 0x68, 0x48, 0x68, 0x49, 0x68, - 0x4a, 0x68, 0x4b, 0x68, 0x4c, 0x68, 0x4d, 0x68, 0x4e, 0x68, 0x4f, - 0x68, 0x50, 0x68, 0x51, 0x68, 0x52, 0x68, 0x53, 0x68, 0x54}; -const uint8_t HuffDecoderCommon::table1_319_emit_[36] = { - 0x68, 0x55, 0x68, 0x56, 0x68, 0x57, 0x68, 0x59, 0x68, 0x6a, 0x68, 0x6b, - 0x68, 0x71, 0x68, 0x76, 0x68, 0x77, 0x68, 0x78, 0x68, 0x79, 0x68, 0x7a, - 0x68, 0x26, 0x68, 0x2a, 0x68, 0x2c, 0x68, 0x3b, 0x68, 0x58, 0x68, 0x5a}; -const uint8_t HuffDecoderCommon::table1_320_emit_[8] = {0x6c, 0x30, 0x6c, 0x31, - 0x6c, 0x32, 0x6c, 0x61}; -const uint8_t HuffDecoderCommon::table1_321_emit_[8] = {0x6c, 0x63, 0x6c, 0x65, - 0x6c, 0x69, 0x6c, 0x6f}; -const uint8_t HuffDecoderCommon::table1_322_emit_[12] = { - 0x6c, 0x73, 0x6c, 0x74, 0x6c, 0x20, 0x6c, 0x25, 0x6c, 0x2d, 0x6c, 0x2e}; -const uint8_t HuffDecoderCommon::table1_323_emit_[16] = { - 0x6c, 0x2f, 0x6c, 0x33, 0x6c, 0x34, 0x6c, 0x35, - 0x6c, 0x36, 0x6c, 0x37, 0x6c, 0x38, 0x6c, 0x39}; -const uint8_t HuffDecoderCommon::table1_324_emit_[16] = { - 0x6c, 0x3d, 0x6c, 0x41, 0x6c, 0x5f, 0x6c, 0x62, - 0x6c, 0x64, 0x6c, 0x66, 0x6c, 0x67, 0x6c, 0x68}; -const uint8_t HuffDecoderCommon::table1_325_emit_[19] = { - 0x6c, 0x6c, 0x6d, 0x6c, 0x6e, 0x6c, 0x70, 0x6c, 0x72, 0x6c, - 0x75, 0x6c, 0x3a, 0x6c, 0x42, 0x6c, 0x43, 0x6c, 0x44}; -const uint16_t HuffDecoderCommon::table1_325_inner_[10] = { - 0x001c, 0x005c, 0x00dc, 0x015c, 0x01dc, - 0x025c, 0x02dd, 0x035d, 0x03dd, 0x045d}; -const uint8_t HuffDecoderCommon::table1_326_emit_[32] = { - 0x6c, 0x45, 0x6c, 0x46, 0x6c, 0x47, 0x6c, 0x48, 0x6c, 0x49, 0x6c, - 0x4a, 0x6c, 0x4b, 0x6c, 0x4c, 0x6c, 0x4d, 0x6c, 0x4e, 0x6c, 0x4f, - 0x6c, 0x50, 0x6c, 0x51, 0x6c, 0x52, 0x6c, 0x53, 0x6c, 0x54}; -const uint8_t HuffDecoderCommon::table1_327_emit_[36] = { - 0x6c, 0x55, 0x6c, 0x56, 0x6c, 0x57, 0x6c, 0x59, 0x6c, 0x6a, 0x6c, 0x6b, - 0x6c, 0x71, 0x6c, 0x76, 0x6c, 0x77, 0x6c, 0x78, 0x6c, 0x79, 0x6c, 0x7a, - 0x6c, 0x26, 0x6c, 0x2a, 0x6c, 0x2c, 0x6c, 0x3b, 0x6c, 0x58, 0x6c, 0x5a}; -const uint8_t HuffDecoderCommon::table1_328_emit_[8] = {0x6d, 0x30, 0x6d, 0x31, - 0x6d, 0x32, 0x6d, 0x61}; -const uint8_t HuffDecoderCommon::table1_329_emit_[8] = {0x6d, 0x63, 0x6d, 0x65, - 0x6d, 0x69, 0x6d, 0x6f}; -const uint8_t HuffDecoderCommon::table1_330_emit_[12] = { - 0x6d, 0x73, 0x6d, 0x74, 0x6d, 0x20, 0x6d, 0x25, 0x6d, 0x2d, 0x6d, 0x2e}; -const uint8_t HuffDecoderCommon::table1_331_emit_[16] = { - 0x6d, 0x2f, 0x6d, 0x33, 0x6d, 0x34, 0x6d, 0x35, - 0x6d, 0x36, 0x6d, 0x37, 0x6d, 0x38, 0x6d, 0x39}; -const uint8_t HuffDecoderCommon::table1_332_emit_[16] = { - 0x6d, 0x3d, 0x6d, 0x41, 0x6d, 0x5f, 0x6d, 0x62, - 0x6d, 0x64, 0x6d, 0x66, 0x6d, 0x67, 0x6d, 0x68}; -const uint8_t HuffDecoderCommon::table1_333_emit_[19] = { - 0x6d, 0x6c, 0x6d, 0x6d, 0x6e, 0x6d, 0x70, 0x6d, 0x72, 0x6d, - 0x75, 0x6d, 0x3a, 0x6d, 0x42, 0x6d, 0x43, 0x6d, 0x44}; -const uint16_t HuffDecoderCommon::table1_333_inner_[10] = { - 0x001c, 0x009c, 0x00dc, 0x015c, 0x01dc, - 0x025c, 0x02dd, 0x035d, 0x03dd, 0x045d}; -const uint8_t HuffDecoderCommon::table1_334_emit_[32] = { - 0x6d, 0x45, 0x6d, 0x46, 0x6d, 0x47, 0x6d, 0x48, 0x6d, 0x49, 0x6d, - 0x4a, 0x6d, 0x4b, 0x6d, 0x4c, 0x6d, 0x4d, 0x6d, 0x4e, 0x6d, 0x4f, - 0x6d, 0x50, 0x6d, 0x51, 0x6d, 0x52, 0x6d, 0x53, 0x6d, 0x54}; -const uint8_t HuffDecoderCommon::table1_335_emit_[36] = { - 0x6d, 0x55, 0x6d, 0x56, 0x6d, 0x57, 0x6d, 0x59, 0x6d, 0x6a, 0x6d, 0x6b, - 0x6d, 0x71, 0x6d, 0x76, 0x6d, 0x77, 0x6d, 0x78, 0x6d, 0x79, 0x6d, 0x7a, - 0x6d, 0x26, 0x6d, 0x2a, 0x6d, 0x2c, 0x6d, 0x3b, 0x6d, 0x58, 0x6d, 0x5a}; -const uint8_t HuffDecoderCommon::table1_336_emit_[8] = {0x6e, 0x30, 0x6e, 0x31, - 0x6e, 0x32, 0x6e, 0x61}; -const uint8_t HuffDecoderCommon::table1_337_emit_[8] = {0x6e, 0x63, 0x6e, 0x65, - 0x6e, 0x69, 0x6e, 0x6f}; -const uint8_t HuffDecoderCommon::table1_338_emit_[12] = { - 0x6e, 0x73, 0x6e, 0x74, 0x6e, 0x20, 0x6e, 0x25, 0x6e, 0x2d, 0x6e, 0x2e}; -const uint8_t HuffDecoderCommon::table1_339_emit_[16] = { - 0x6e, 0x2f, 0x6e, 0x33, 0x6e, 0x34, 0x6e, 0x35, - 0x6e, 0x36, 0x6e, 0x37, 0x6e, 0x38, 0x6e, 0x39}; -const uint8_t HuffDecoderCommon::table1_340_emit_[16] = { - 0x6e, 0x3d, 0x6e, 0x41, 0x6e, 0x5f, 0x6e, 0x62, - 0x6e, 0x64, 0x6e, 0x66, 0x6e, 0x67, 0x6e, 0x68}; -const uint8_t HuffDecoderCommon::table1_341_emit_[19] = { - 0x6e, 0x6c, 0x6e, 0x6d, 0x6e, 0x6e, 0x70, 0x6e, 0x72, 0x6e, - 0x75, 0x6e, 0x3a, 0x6e, 0x42, 0x6e, 0x43, 0x6e, 0x44}; -const uint16_t HuffDecoderCommon::table1_341_inner_[10] = { - 0x001c, 0x009c, 0x011c, 0x015c, 0x01dc, - 0x025c, 0x02dd, 0x035d, 0x03dd, 0x045d}; -const uint8_t HuffDecoderCommon::table1_342_emit_[32] = { - 0x6e, 0x45, 0x6e, 0x46, 0x6e, 0x47, 0x6e, 0x48, 0x6e, 0x49, 0x6e, - 0x4a, 0x6e, 0x4b, 0x6e, 0x4c, 0x6e, 0x4d, 0x6e, 0x4e, 0x6e, 0x4f, - 0x6e, 0x50, 0x6e, 0x51, 0x6e, 0x52, 0x6e, 0x53, 0x6e, 0x54}; -const uint8_t HuffDecoderCommon::table1_343_emit_[36] = { - 0x6e, 0x55, 0x6e, 0x56, 0x6e, 0x57, 0x6e, 0x59, 0x6e, 0x6a, 0x6e, 0x6b, - 0x6e, 0x71, 0x6e, 0x76, 0x6e, 0x77, 0x6e, 0x78, 0x6e, 0x79, 0x6e, 0x7a, - 0x6e, 0x26, 0x6e, 0x2a, 0x6e, 0x2c, 0x6e, 0x3b, 0x6e, 0x58, 0x6e, 0x5a}; -const uint8_t HuffDecoderCommon::table1_344_emit_[8] = {0x70, 0x30, 0x70, 0x31, - 0x70, 0x32, 0x70, 0x61}; -const uint8_t HuffDecoderCommon::table1_345_emit_[8] = {0x70, 0x63, 0x70, 0x65, - 0x70, 0x69, 0x70, 0x6f}; -const uint8_t HuffDecoderCommon::table1_346_emit_[12] = { - 0x70, 0x73, 0x70, 0x74, 0x70, 0x20, 0x70, 0x25, 0x70, 0x2d, 0x70, 0x2e}; -const uint8_t HuffDecoderCommon::table1_347_emit_[16] = { - 0x70, 0x2f, 0x70, 0x33, 0x70, 0x34, 0x70, 0x35, - 0x70, 0x36, 0x70, 0x37, 0x70, 0x38, 0x70, 0x39}; -const uint8_t HuffDecoderCommon::table1_348_emit_[16] = { - 0x70, 0x3d, 0x70, 0x41, 0x70, 0x5f, 0x70, 0x62, - 0x70, 0x64, 0x70, 0x66, 0x70, 0x67, 0x70, 0x68}; -const uint8_t HuffDecoderCommon::table1_349_emit_[19] = { - 0x70, 0x6c, 0x70, 0x6d, 0x70, 0x6e, 0x70, 0x70, 0x72, 0x70, - 0x75, 0x70, 0x3a, 0x70, 0x42, 0x70, 0x43, 0x70, 0x44}; -const uint16_t HuffDecoderCommon::table1_349_inner_[10] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x01dc, - 0x025c, 0x02dd, 0x035d, 0x03dd, 0x045d}; -const uint8_t HuffDecoderCommon::table1_350_emit_[32] = { - 0x70, 0x45, 0x70, 0x46, 0x70, 0x47, 0x70, 0x48, 0x70, 0x49, 0x70, - 0x4a, 0x70, 0x4b, 0x70, 0x4c, 0x70, 0x4d, 0x70, 0x4e, 0x70, 0x4f, - 0x70, 0x50, 0x70, 0x51, 0x70, 0x52, 0x70, 0x53, 0x70, 0x54}; -const uint8_t HuffDecoderCommon::table1_351_emit_[36] = { - 0x70, 0x55, 0x70, 0x56, 0x70, 0x57, 0x70, 0x59, 0x70, 0x6a, 0x70, 0x6b, - 0x70, 0x71, 0x70, 0x76, 0x70, 0x77, 0x70, 0x78, 0x70, 0x79, 0x70, 0x7a, - 0x70, 0x26, 0x70, 0x2a, 0x70, 0x2c, 0x70, 0x3b, 0x70, 0x58, 0x70, 0x5a}; -const uint8_t HuffDecoderCommon::table1_352_emit_[8] = {0x72, 0x30, 0x72, 0x31, - 0x72, 0x32, 0x72, 0x61}; -const uint8_t HuffDecoderCommon::table1_353_emit_[8] = {0x72, 0x63, 0x72, 0x65, - 0x72, 0x69, 0x72, 0x6f}; -const uint8_t HuffDecoderCommon::table1_354_emit_[12] = { - 0x72, 0x73, 0x72, 0x74, 0x72, 0x20, 0x72, 0x25, 0x72, 0x2d, 0x72, 0x2e}; -const uint8_t HuffDecoderCommon::table1_355_emit_[16] = { - 0x72, 0x2f, 0x72, 0x33, 0x72, 0x34, 0x72, 0x35, - 0x72, 0x36, 0x72, 0x37, 0x72, 0x38, 0x72, 0x39}; -const uint8_t HuffDecoderCommon::table1_356_emit_[16] = { - 0x72, 0x3d, 0x72, 0x41, 0x72, 0x5f, 0x72, 0x62, - 0x72, 0x64, 0x72, 0x66, 0x72, 0x67, 0x72, 0x68}; -const uint8_t HuffDecoderCommon::table1_357_emit_[19] = { - 0x72, 0x6c, 0x72, 0x6d, 0x72, 0x6e, 0x72, 0x70, 0x72, 0x72, - 0x75, 0x72, 0x3a, 0x72, 0x42, 0x72, 0x43, 0x72, 0x44}; -const uint16_t HuffDecoderCommon::table1_357_inner_[10] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021c, - 0x025c, 0x02dd, 0x035d, 0x03dd, 0x045d}; -const uint8_t HuffDecoderCommon::table1_358_emit_[32] = { - 0x72, 0x45, 0x72, 0x46, 0x72, 0x47, 0x72, 0x48, 0x72, 0x49, 0x72, - 0x4a, 0x72, 0x4b, 0x72, 0x4c, 0x72, 0x4d, 0x72, 0x4e, 0x72, 0x4f, - 0x72, 0x50, 0x72, 0x51, 0x72, 0x52, 0x72, 0x53, 0x72, 0x54}; -const uint8_t HuffDecoderCommon::table1_359_emit_[36] = { - 0x72, 0x55, 0x72, 0x56, 0x72, 0x57, 0x72, 0x59, 0x72, 0x6a, 0x72, 0x6b, - 0x72, 0x71, 0x72, 0x76, 0x72, 0x77, 0x72, 0x78, 0x72, 0x79, 0x72, 0x7a, - 0x72, 0x26, 0x72, 0x2a, 0x72, 0x2c, 0x72, 0x3b, 0x72, 0x58, 0x72, 0x5a}; -const uint8_t HuffDecoderCommon::table1_360_emit_[8] = {0x75, 0x30, 0x75, 0x31, - 0x75, 0x32, 0x75, 0x61}; -const uint8_t HuffDecoderCommon::table1_361_emit_[8] = {0x75, 0x63, 0x75, 0x65, - 0x75, 0x69, 0x75, 0x6f}; -const uint8_t HuffDecoderCommon::table1_362_emit_[12] = { - 0x75, 0x73, 0x75, 0x74, 0x75, 0x20, 0x75, 0x25, 0x75, 0x2d, 0x75, 0x2e}; -const uint8_t HuffDecoderCommon::table1_363_emit_[16] = { - 0x75, 0x2f, 0x75, 0x33, 0x75, 0x34, 0x75, 0x35, - 0x75, 0x36, 0x75, 0x37, 0x75, 0x38, 0x75, 0x39}; -const uint8_t HuffDecoderCommon::table1_364_emit_[16] = { - 0x75, 0x3d, 0x75, 0x41, 0x75, 0x5f, 0x75, 0x62, - 0x75, 0x64, 0x75, 0x66, 0x75, 0x67, 0x75, 0x68}; -const uint8_t HuffDecoderCommon::table1_365_emit_[19] = { - 0x75, 0x6c, 0x75, 0x6d, 0x75, 0x6e, 0x75, 0x70, 0x75, 0x72, - 0x75, 0x75, 0x3a, 0x75, 0x42, 0x75, 0x43, 0x75, 0x44}; -const uint16_t HuffDecoderCommon::table1_365_inner_[10] = { - 0x001c, 0x009c, 0x011c, 0x019c, 0x021c, - 0x029c, 0x02dd, 0x035d, 0x03dd, 0x045d}; -const uint8_t HuffDecoderCommon::table1_366_emit_[32] = { - 0x75, 0x45, 0x75, 0x46, 0x75, 0x47, 0x75, 0x48, 0x75, 0x49, 0x75, - 0x4a, 0x75, 0x4b, 0x75, 0x4c, 0x75, 0x4d, 0x75, 0x4e, 0x75, 0x4f, - 0x75, 0x50, 0x75, 0x51, 0x75, 0x52, 0x75, 0x53, 0x75, 0x54}; -const uint8_t HuffDecoderCommon::table1_367_emit_[36] = { - 0x75, 0x55, 0x75, 0x56, 0x75, 0x57, 0x75, 0x59, 0x75, 0x6a, 0x75, 0x6b, - 0x75, 0x71, 0x75, 0x76, 0x75, 0x77, 0x75, 0x78, 0x75, 0x79, 0x75, 0x7a, - 0x75, 0x26, 0x75, 0x2a, 0x75, 0x2c, 0x75, 0x3b, 0x75, 0x58, 0x75, 0x5a}; -const uint8_t HuffDecoderCommon::table1_368_emit_[16] = { - 0x3a, 0x30, 0x3a, 0x31, 0x3a, 0x32, 0x3a, 0x61, - 0x3a, 0x63, 0x3a, 0x65, 0x3a, 0x69, 0x3a, 0x6f}; -const uint8_t HuffDecoderCommon::table1_369_emit_[28] = { - 0x3a, 0x73, 0x3a, 0x74, 0x3a, 0x20, 0x3a, 0x25, 0x3a, 0x2d, - 0x3a, 0x2e, 0x3a, 0x2f, 0x3a, 0x33, 0x3a, 0x34, 0x3a, 0x35, - 0x3a, 0x36, 0x3a, 0x37, 0x3a, 0x38, 0x3a, 0x39}; -const uint16_t HuffDecoderCommon::table1_369_inner_[14] = { - 0x001c, 0x009c, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, - 0x039d, 0x041d, 0x049d, 0x051d, 0x059d, 0x061d, 0x069d}; -const uint8_t HuffDecoderCommon::table1_369_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, - 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13}; -const uint8_t HuffDecoderCommon::table1_370_emit_[35] = { - 0x3a, 0x3d, 0x3a, 0x41, 0x3a, 0x5f, 0x3a, 0x62, 0x3a, 0x64, 0x3a, 0x66, - 0x3a, 0x67, 0x3a, 0x68, 0x3a, 0x6c, 0x3a, 0x6d, 0x3a, 0x6e, 0x3a, 0x70, - 0x3a, 0x72, 0x3a, 0x75, 0x3a, 0x3a, 0x42, 0x3a, 0x43, 0x3a, 0x44}; -const uint16_t HuffDecoderCommon::table1_370_inner_[18] = { - 0x001d, 0x009d, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, 0x039d, 0x041d, - 0x049d, 0x051d, 0x059d, 0x061d, 0x069d, 0x071e, 0x075e, 0x07de, 0x085e}; -const uint8_t HuffDecoderCommon::table1_370_outer_[64] = { - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, - 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17}; -const uint8_t HuffDecoderCommon::table1_371_emit_[68] = { - 0x3a, 0x45, 0x3a, 0x46, 0x3a, 0x47, 0x3a, 0x48, 0x3a, 0x49, 0x3a, 0x4a, - 0x3a, 0x4b, 0x3a, 0x4c, 0x3a, 0x4d, 0x3a, 0x4e, 0x3a, 0x4f, 0x3a, 0x50, - 0x3a, 0x51, 0x3a, 0x52, 0x3a, 0x53, 0x3a, 0x54, 0x3a, 0x55, 0x3a, 0x56, - 0x3a, 0x57, 0x3a, 0x59, 0x3a, 0x6a, 0x3a, 0x6b, 0x3a, 0x71, 0x3a, 0x76, - 0x3a, 0x77, 0x3a, 0x78, 0x3a, 0x79, 0x3a, 0x7a, 0x3a, 0x26, 0x3a, 0x2a, - 0x3a, 0x2c, 0x3a, 0x3b, 0x3a, 0x58, 0x3a, 0x5a}; -const uint16_t HuffDecoderCommon::table1_371_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0b1e, 0x0b9e, 0x0c1e, 0x0c9e, 0x0d1e, - 0x0d9e, 0x0e1f, 0x0e9f, 0x0f1f, 0x0f9f, 0x101f, 0x109f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_371_outer_[64] = { - 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, - 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, - 24, 24, 25, 25, 26, 26, 27, 27, 28, 29, 30, 31, 32, 33, 34, 34}; -const uint8_t HuffDecoderCommon::table1_372_emit_[16] = { - 0x42, 0x30, 0x42, 0x31, 0x42, 0x32, 0x42, 0x61, - 0x42, 0x63, 0x42, 0x65, 0x42, 0x69, 0x42, 0x6f}; -const uint8_t HuffDecoderCommon::table1_373_emit_[28] = { - 0x42, 0x73, 0x42, 0x74, 0x42, 0x20, 0x42, 0x25, 0x42, 0x2d, - 0x42, 0x2e, 0x42, 0x2f, 0x42, 0x33, 0x42, 0x34, 0x42, 0x35, - 0x42, 0x36, 0x42, 0x37, 0x42, 0x38, 0x42, 0x39}; -const uint8_t HuffDecoderCommon::table1_374_emit_[35] = { - 0x42, 0x3d, 0x42, 0x41, 0x42, 0x5f, 0x42, 0x62, 0x42, 0x64, 0x42, 0x66, - 0x42, 0x67, 0x42, 0x68, 0x42, 0x6c, 0x42, 0x6d, 0x42, 0x6e, 0x42, 0x70, - 0x42, 0x72, 0x42, 0x75, 0x42, 0x3a, 0x42, 0x42, 0x43, 0x42, 0x44}; -const uint16_t HuffDecoderCommon::table1_374_inner_[18] = { - 0x001d, 0x009d, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, 0x039d, 0x041d, - 0x049d, 0x051d, 0x059d, 0x061d, 0x069d, 0x071e, 0x079e, 0x07de, 0x085e}; -const uint8_t HuffDecoderCommon::table1_375_emit_[68] = { - 0x42, 0x45, 0x42, 0x46, 0x42, 0x47, 0x42, 0x48, 0x42, 0x49, 0x42, 0x4a, - 0x42, 0x4b, 0x42, 0x4c, 0x42, 0x4d, 0x42, 0x4e, 0x42, 0x4f, 0x42, 0x50, - 0x42, 0x51, 0x42, 0x52, 0x42, 0x53, 0x42, 0x54, 0x42, 0x55, 0x42, 0x56, - 0x42, 0x57, 0x42, 0x59, 0x42, 0x6a, 0x42, 0x6b, 0x42, 0x71, 0x42, 0x76, - 0x42, 0x77, 0x42, 0x78, 0x42, 0x79, 0x42, 0x7a, 0x42, 0x26, 0x42, 0x2a, - 0x42, 0x2c, 0x42, 0x3b, 0x42, 0x58, 0x42, 0x5a}; -const uint8_t HuffDecoderCommon::table1_376_emit_[16] = { - 0x43, 0x30, 0x43, 0x31, 0x43, 0x32, 0x43, 0x61, - 0x43, 0x63, 0x43, 0x65, 0x43, 0x69, 0x43, 0x6f}; -const uint8_t HuffDecoderCommon::table1_377_emit_[28] = { - 0x43, 0x73, 0x43, 0x74, 0x43, 0x20, 0x43, 0x25, 0x43, 0x2d, - 0x43, 0x2e, 0x43, 0x2f, 0x43, 0x33, 0x43, 0x34, 0x43, 0x35, - 0x43, 0x36, 0x43, 0x37, 0x43, 0x38, 0x43, 0x39}; -const uint8_t HuffDecoderCommon::table1_378_emit_[35] = { - 0x43, 0x3d, 0x43, 0x41, 0x43, 0x5f, 0x43, 0x62, 0x43, 0x64, 0x43, 0x66, - 0x43, 0x67, 0x43, 0x68, 0x43, 0x6c, 0x43, 0x6d, 0x43, 0x6e, 0x43, 0x70, - 0x43, 0x72, 0x43, 0x75, 0x43, 0x3a, 0x43, 0x42, 0x43, 0x43, 0x44}; -const uint16_t HuffDecoderCommon::table1_378_inner_[18] = { - 0x001d, 0x009d, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, 0x039d, 0x041d, - 0x049d, 0x051d, 0x059d, 0x061d, 0x069d, 0x071e, 0x079e, 0x081e, 0x085e}; -const uint8_t HuffDecoderCommon::table1_379_emit_[68] = { - 0x43, 0x45, 0x43, 0x46, 0x43, 0x47, 0x43, 0x48, 0x43, 0x49, 0x43, 0x4a, - 0x43, 0x4b, 0x43, 0x4c, 0x43, 0x4d, 0x43, 0x4e, 0x43, 0x4f, 0x43, 0x50, - 0x43, 0x51, 0x43, 0x52, 0x43, 0x53, 0x43, 0x54, 0x43, 0x55, 0x43, 0x56, - 0x43, 0x57, 0x43, 0x59, 0x43, 0x6a, 0x43, 0x6b, 0x43, 0x71, 0x43, 0x76, - 0x43, 0x77, 0x43, 0x78, 0x43, 0x79, 0x43, 0x7a, 0x43, 0x26, 0x43, 0x2a, - 0x43, 0x2c, 0x43, 0x3b, 0x43, 0x58, 0x43, 0x5a}; -const uint8_t HuffDecoderCommon::table1_380_emit_[16] = { - 0x44, 0x30, 0x44, 0x31, 0x44, 0x32, 0x44, 0x61, - 0x44, 0x63, 0x44, 0x65, 0x44, 0x69, 0x44, 0x6f}; -const uint8_t HuffDecoderCommon::table1_381_emit_[28] = { - 0x44, 0x73, 0x44, 0x74, 0x44, 0x20, 0x44, 0x25, 0x44, 0x2d, - 0x44, 0x2e, 0x44, 0x2f, 0x44, 0x33, 0x44, 0x34, 0x44, 0x35, - 0x44, 0x36, 0x44, 0x37, 0x44, 0x38, 0x44, 0x39}; -const uint8_t HuffDecoderCommon::table1_382_emit_[36] = { - 0x44, 0x3d, 0x44, 0x41, 0x44, 0x5f, 0x44, 0x62, 0x44, 0x64, 0x44, 0x66, - 0x44, 0x67, 0x44, 0x68, 0x44, 0x6c, 0x44, 0x6d, 0x44, 0x6e, 0x44, 0x70, - 0x44, 0x72, 0x44, 0x75, 0x44, 0x3a, 0x44, 0x42, 0x44, 0x43, 0x44, 0x44}; -const uint16_t HuffDecoderCommon::table1_382_inner_[18] = { - 0x001d, 0x009d, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, 0x039d, 0x041d, - 0x049d, 0x051d, 0x059d, 0x061d, 0x069d, 0x071e, 0x079e, 0x081e, 0x089e}; -const uint8_t HuffDecoderCommon::table1_383_emit_[68] = { - 0x44, 0x45, 0x44, 0x46, 0x44, 0x47, 0x44, 0x48, 0x44, 0x49, 0x44, 0x4a, - 0x44, 0x4b, 0x44, 0x4c, 0x44, 0x4d, 0x44, 0x4e, 0x44, 0x4f, 0x44, 0x50, - 0x44, 0x51, 0x44, 0x52, 0x44, 0x53, 0x44, 0x54, 0x44, 0x55, 0x44, 0x56, - 0x44, 0x57, 0x44, 0x59, 0x44, 0x6a, 0x44, 0x6b, 0x44, 0x71, 0x44, 0x76, - 0x44, 0x77, 0x44, 0x78, 0x44, 0x79, 0x44, 0x7a, 0x44, 0x26, 0x44, 0x2a, - 0x44, 0x2c, 0x44, 0x3b, 0x44, 0x58, 0x44, 0x5a}; -const uint8_t HuffDecoderCommon::table1_384_emit_[16] = { - 0x45, 0x30, 0x45, 0x31, 0x45, 0x32, 0x45, 0x61, - 0x45, 0x63, 0x45, 0x65, 0x45, 0x69, 0x45, 0x6f}; -const uint8_t HuffDecoderCommon::table1_385_emit_[28] = { - 0x45, 0x73, 0x45, 0x74, 0x45, 0x20, 0x45, 0x25, 0x45, 0x2d, - 0x45, 0x2e, 0x45, 0x2f, 0x45, 0x33, 0x45, 0x34, 0x45, 0x35, - 0x45, 0x36, 0x45, 0x37, 0x45, 0x38, 0x45, 0x39}; -const uint8_t HuffDecoderCommon::table1_386_emit_[36] = { - 0x45, 0x3d, 0x45, 0x41, 0x45, 0x5f, 0x45, 0x62, 0x45, 0x64, 0x45, 0x66, - 0x45, 0x67, 0x45, 0x68, 0x45, 0x6c, 0x45, 0x6d, 0x45, 0x6e, 0x45, 0x70, - 0x45, 0x72, 0x45, 0x75, 0x45, 0x3a, 0x45, 0x42, 0x45, 0x43, 0x45, 0x44}; -const uint8_t HuffDecoderCommon::table1_387_emit_[67] = { - 0x45, 0x45, 0x46, 0x45, 0x47, 0x45, 0x48, 0x45, 0x49, 0x45, 0x4a, 0x45, - 0x4b, 0x45, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x45, 0x4f, 0x45, 0x50, 0x45, - 0x51, 0x45, 0x52, 0x45, 0x53, 0x45, 0x54, 0x45, 0x55, 0x45, 0x56, 0x45, - 0x57, 0x45, 0x59, 0x45, 0x6a, 0x45, 0x6b, 0x45, 0x71, 0x45, 0x76, 0x45, - 0x77, 0x45, 0x78, 0x45, 0x79, 0x45, 0x7a, 0x45, 0x26, 0x45, 0x2a, 0x45, - 0x2c, 0x45, 0x3b, 0x45, 0x58, 0x45, 0x5a}; -const uint16_t HuffDecoderCommon::table1_387_inner_[35] = { - 0x001e, 0x005e, 0x00de, 0x015e, 0x01de, 0x025e, 0x02de, 0x035e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_388_emit_[16] = { - 0x46, 0x30, 0x46, 0x31, 0x46, 0x32, 0x46, 0x61, - 0x46, 0x63, 0x46, 0x65, 0x46, 0x69, 0x46, 0x6f}; -const uint8_t HuffDecoderCommon::table1_389_emit_[28] = { - 0x46, 0x73, 0x46, 0x74, 0x46, 0x20, 0x46, 0x25, 0x46, 0x2d, - 0x46, 0x2e, 0x46, 0x2f, 0x46, 0x33, 0x46, 0x34, 0x46, 0x35, - 0x46, 0x36, 0x46, 0x37, 0x46, 0x38, 0x46, 0x39}; -const uint8_t HuffDecoderCommon::table1_390_emit_[36] = { - 0x46, 0x3d, 0x46, 0x41, 0x46, 0x5f, 0x46, 0x62, 0x46, 0x64, 0x46, 0x66, - 0x46, 0x67, 0x46, 0x68, 0x46, 0x6c, 0x46, 0x6d, 0x46, 0x6e, 0x46, 0x70, - 0x46, 0x72, 0x46, 0x75, 0x46, 0x3a, 0x46, 0x42, 0x46, 0x43, 0x46, 0x44}; -const uint8_t HuffDecoderCommon::table1_391_emit_[67] = { - 0x46, 0x45, 0x46, 0x46, 0x47, 0x46, 0x48, 0x46, 0x49, 0x46, 0x4a, 0x46, - 0x4b, 0x46, 0x4c, 0x46, 0x4d, 0x46, 0x4e, 0x46, 0x4f, 0x46, 0x50, 0x46, - 0x51, 0x46, 0x52, 0x46, 0x53, 0x46, 0x54, 0x46, 0x55, 0x46, 0x56, 0x46, - 0x57, 0x46, 0x59, 0x46, 0x6a, 0x46, 0x6b, 0x46, 0x71, 0x46, 0x76, 0x46, - 0x77, 0x46, 0x78, 0x46, 0x79, 0x46, 0x7a, 0x46, 0x26, 0x46, 0x2a, 0x46, - 0x2c, 0x46, 0x3b, 0x46, 0x58, 0x46, 0x5a}; -const uint16_t HuffDecoderCommon::table1_391_inner_[35] = { - 0x001e, 0x009e, 0x00de, 0x015e, 0x01de, 0x025e, 0x02de, 0x035e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_392_emit_[16] = { - 0x47, 0x30, 0x47, 0x31, 0x47, 0x32, 0x47, 0x61, - 0x47, 0x63, 0x47, 0x65, 0x47, 0x69, 0x47, 0x6f}; -const uint8_t HuffDecoderCommon::table1_393_emit_[28] = { - 0x47, 0x73, 0x47, 0x74, 0x47, 0x20, 0x47, 0x25, 0x47, 0x2d, - 0x47, 0x2e, 0x47, 0x2f, 0x47, 0x33, 0x47, 0x34, 0x47, 0x35, - 0x47, 0x36, 0x47, 0x37, 0x47, 0x38, 0x47, 0x39}; -const uint8_t HuffDecoderCommon::table1_394_emit_[36] = { - 0x47, 0x3d, 0x47, 0x41, 0x47, 0x5f, 0x47, 0x62, 0x47, 0x64, 0x47, 0x66, - 0x47, 0x67, 0x47, 0x68, 0x47, 0x6c, 0x47, 0x6d, 0x47, 0x6e, 0x47, 0x70, - 0x47, 0x72, 0x47, 0x75, 0x47, 0x3a, 0x47, 0x42, 0x47, 0x43, 0x47, 0x44}; -const uint8_t HuffDecoderCommon::table1_395_emit_[67] = { - 0x47, 0x45, 0x47, 0x46, 0x47, 0x47, 0x48, 0x47, 0x49, 0x47, 0x4a, 0x47, - 0x4b, 0x47, 0x4c, 0x47, 0x4d, 0x47, 0x4e, 0x47, 0x4f, 0x47, 0x50, 0x47, - 0x51, 0x47, 0x52, 0x47, 0x53, 0x47, 0x54, 0x47, 0x55, 0x47, 0x56, 0x47, - 0x57, 0x47, 0x59, 0x47, 0x6a, 0x47, 0x6b, 0x47, 0x71, 0x47, 0x76, 0x47, - 0x77, 0x47, 0x78, 0x47, 0x79, 0x47, 0x7a, 0x47, 0x26, 0x47, 0x2a, 0x47, - 0x2c, 0x47, 0x3b, 0x47, 0x58, 0x47, 0x5a}; -const uint16_t HuffDecoderCommon::table1_395_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x015e, 0x01de, 0x025e, 0x02de, 0x035e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_396_emit_[16] = { - 0x48, 0x30, 0x48, 0x31, 0x48, 0x32, 0x48, 0x61, - 0x48, 0x63, 0x48, 0x65, 0x48, 0x69, 0x48, 0x6f}; -const uint8_t HuffDecoderCommon::table1_397_emit_[28] = { - 0x48, 0x73, 0x48, 0x74, 0x48, 0x20, 0x48, 0x25, 0x48, 0x2d, - 0x48, 0x2e, 0x48, 0x2f, 0x48, 0x33, 0x48, 0x34, 0x48, 0x35, - 0x48, 0x36, 0x48, 0x37, 0x48, 0x38, 0x48, 0x39}; -const uint8_t HuffDecoderCommon::table1_398_emit_[36] = { - 0x48, 0x3d, 0x48, 0x41, 0x48, 0x5f, 0x48, 0x62, 0x48, 0x64, 0x48, 0x66, - 0x48, 0x67, 0x48, 0x68, 0x48, 0x6c, 0x48, 0x6d, 0x48, 0x6e, 0x48, 0x70, - 0x48, 0x72, 0x48, 0x75, 0x48, 0x3a, 0x48, 0x42, 0x48, 0x43, 0x48, 0x44}; -const uint8_t HuffDecoderCommon::table1_399_emit_[67] = { - 0x48, 0x45, 0x48, 0x46, 0x48, 0x47, 0x48, 0x48, 0x49, 0x48, 0x4a, 0x48, - 0x4b, 0x48, 0x4c, 0x48, 0x4d, 0x48, 0x4e, 0x48, 0x4f, 0x48, 0x50, 0x48, - 0x51, 0x48, 0x52, 0x48, 0x53, 0x48, 0x54, 0x48, 0x55, 0x48, 0x56, 0x48, - 0x57, 0x48, 0x59, 0x48, 0x6a, 0x48, 0x6b, 0x48, 0x71, 0x48, 0x76, 0x48, - 0x77, 0x48, 0x78, 0x48, 0x79, 0x48, 0x7a, 0x48, 0x26, 0x48, 0x2a, 0x48, - 0x2c, 0x48, 0x3b, 0x48, 0x58, 0x48, 0x5a}; -const uint16_t HuffDecoderCommon::table1_399_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x01de, 0x025e, 0x02de, 0x035e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_400_emit_[16] = { - 0x49, 0x30, 0x49, 0x31, 0x49, 0x32, 0x49, 0x61, - 0x49, 0x63, 0x49, 0x65, 0x49, 0x69, 0x49, 0x6f}; -const uint8_t HuffDecoderCommon::table1_401_emit_[28] = { - 0x49, 0x73, 0x49, 0x74, 0x49, 0x20, 0x49, 0x25, 0x49, 0x2d, - 0x49, 0x2e, 0x49, 0x2f, 0x49, 0x33, 0x49, 0x34, 0x49, 0x35, - 0x49, 0x36, 0x49, 0x37, 0x49, 0x38, 0x49, 0x39}; -const uint8_t HuffDecoderCommon::table1_402_emit_[36] = { - 0x49, 0x3d, 0x49, 0x41, 0x49, 0x5f, 0x49, 0x62, 0x49, 0x64, 0x49, 0x66, - 0x49, 0x67, 0x49, 0x68, 0x49, 0x6c, 0x49, 0x6d, 0x49, 0x6e, 0x49, 0x70, - 0x49, 0x72, 0x49, 0x75, 0x49, 0x3a, 0x49, 0x42, 0x49, 0x43, 0x49, 0x44}; -const uint8_t HuffDecoderCommon::table1_403_emit_[67] = { - 0x49, 0x45, 0x49, 0x46, 0x49, 0x47, 0x49, 0x48, 0x49, 0x49, 0x4a, 0x49, - 0x4b, 0x49, 0x4c, 0x49, 0x4d, 0x49, 0x4e, 0x49, 0x4f, 0x49, 0x50, 0x49, - 0x51, 0x49, 0x52, 0x49, 0x53, 0x49, 0x54, 0x49, 0x55, 0x49, 0x56, 0x49, - 0x57, 0x49, 0x59, 0x49, 0x6a, 0x49, 0x6b, 0x49, 0x71, 0x49, 0x76, 0x49, - 0x77, 0x49, 0x78, 0x49, 0x79, 0x49, 0x7a, 0x49, 0x26, 0x49, 0x2a, 0x49, - 0x2c, 0x49, 0x3b, 0x49, 0x58, 0x49, 0x5a}; -const uint16_t HuffDecoderCommon::table1_403_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x025e, 0x02de, 0x035e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_404_emit_[16] = { - 0x4a, 0x30, 0x4a, 0x31, 0x4a, 0x32, 0x4a, 0x61, - 0x4a, 0x63, 0x4a, 0x65, 0x4a, 0x69, 0x4a, 0x6f}; -const uint8_t HuffDecoderCommon::table1_405_emit_[28] = { - 0x4a, 0x73, 0x4a, 0x74, 0x4a, 0x20, 0x4a, 0x25, 0x4a, 0x2d, - 0x4a, 0x2e, 0x4a, 0x2f, 0x4a, 0x33, 0x4a, 0x34, 0x4a, 0x35, - 0x4a, 0x36, 0x4a, 0x37, 0x4a, 0x38, 0x4a, 0x39}; -const uint8_t HuffDecoderCommon::table1_406_emit_[36] = { - 0x4a, 0x3d, 0x4a, 0x41, 0x4a, 0x5f, 0x4a, 0x62, 0x4a, 0x64, 0x4a, 0x66, - 0x4a, 0x67, 0x4a, 0x68, 0x4a, 0x6c, 0x4a, 0x6d, 0x4a, 0x6e, 0x4a, 0x70, - 0x4a, 0x72, 0x4a, 0x75, 0x4a, 0x3a, 0x4a, 0x42, 0x4a, 0x43, 0x4a, 0x44}; -const uint8_t HuffDecoderCommon::table1_407_emit_[67] = { - 0x4a, 0x45, 0x4a, 0x46, 0x4a, 0x47, 0x4a, 0x48, 0x4a, 0x49, 0x4a, 0x4a, - 0x4b, 0x4a, 0x4c, 0x4a, 0x4d, 0x4a, 0x4e, 0x4a, 0x4f, 0x4a, 0x50, 0x4a, - 0x51, 0x4a, 0x52, 0x4a, 0x53, 0x4a, 0x54, 0x4a, 0x55, 0x4a, 0x56, 0x4a, - 0x57, 0x4a, 0x59, 0x4a, 0x6a, 0x4a, 0x6b, 0x4a, 0x71, 0x4a, 0x76, 0x4a, - 0x77, 0x4a, 0x78, 0x4a, 0x79, 0x4a, 0x7a, 0x4a, 0x26, 0x4a, 0x2a, 0x4a, - 0x2c, 0x4a, 0x3b, 0x4a, 0x58, 0x4a, 0x5a}; -const uint16_t HuffDecoderCommon::table1_407_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x02de, 0x035e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_408_emit_[16] = { - 0x4b, 0x30, 0x4b, 0x31, 0x4b, 0x32, 0x4b, 0x61, - 0x4b, 0x63, 0x4b, 0x65, 0x4b, 0x69, 0x4b, 0x6f}; -const uint8_t HuffDecoderCommon::table1_409_emit_[28] = { - 0x4b, 0x73, 0x4b, 0x74, 0x4b, 0x20, 0x4b, 0x25, 0x4b, 0x2d, - 0x4b, 0x2e, 0x4b, 0x2f, 0x4b, 0x33, 0x4b, 0x34, 0x4b, 0x35, - 0x4b, 0x36, 0x4b, 0x37, 0x4b, 0x38, 0x4b, 0x39}; -const uint8_t HuffDecoderCommon::table1_410_emit_[36] = { - 0x4b, 0x3d, 0x4b, 0x41, 0x4b, 0x5f, 0x4b, 0x62, 0x4b, 0x64, 0x4b, 0x66, - 0x4b, 0x67, 0x4b, 0x68, 0x4b, 0x6c, 0x4b, 0x6d, 0x4b, 0x6e, 0x4b, 0x70, - 0x4b, 0x72, 0x4b, 0x75, 0x4b, 0x3a, 0x4b, 0x42, 0x4b, 0x43, 0x4b, 0x44}; -const uint8_t HuffDecoderCommon::table1_411_emit_[67] = { - 0x4b, 0x45, 0x4b, 0x46, 0x4b, 0x47, 0x4b, 0x48, 0x4b, 0x49, 0x4b, 0x4a, - 0x4b, 0x4b, 0x4c, 0x4b, 0x4d, 0x4b, 0x4e, 0x4b, 0x4f, 0x4b, 0x50, 0x4b, - 0x51, 0x4b, 0x52, 0x4b, 0x53, 0x4b, 0x54, 0x4b, 0x55, 0x4b, 0x56, 0x4b, - 0x57, 0x4b, 0x59, 0x4b, 0x6a, 0x4b, 0x6b, 0x4b, 0x71, 0x4b, 0x76, 0x4b, - 0x77, 0x4b, 0x78, 0x4b, 0x79, 0x4b, 0x7a, 0x4b, 0x26, 0x4b, 0x2a, 0x4b, - 0x2c, 0x4b, 0x3b, 0x4b, 0x58, 0x4b, 0x5a}; -const uint16_t HuffDecoderCommon::table1_411_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x035e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_412_emit_[16] = { - 0x4c, 0x30, 0x4c, 0x31, 0x4c, 0x32, 0x4c, 0x61, - 0x4c, 0x63, 0x4c, 0x65, 0x4c, 0x69, 0x4c, 0x6f}; -const uint8_t HuffDecoderCommon::table1_413_emit_[28] = { - 0x4c, 0x73, 0x4c, 0x74, 0x4c, 0x20, 0x4c, 0x25, 0x4c, 0x2d, - 0x4c, 0x2e, 0x4c, 0x2f, 0x4c, 0x33, 0x4c, 0x34, 0x4c, 0x35, - 0x4c, 0x36, 0x4c, 0x37, 0x4c, 0x38, 0x4c, 0x39}; -const uint8_t HuffDecoderCommon::table1_414_emit_[36] = { - 0x4c, 0x3d, 0x4c, 0x41, 0x4c, 0x5f, 0x4c, 0x62, 0x4c, 0x64, 0x4c, 0x66, - 0x4c, 0x67, 0x4c, 0x68, 0x4c, 0x6c, 0x4c, 0x6d, 0x4c, 0x6e, 0x4c, 0x70, - 0x4c, 0x72, 0x4c, 0x75, 0x4c, 0x3a, 0x4c, 0x42, 0x4c, 0x43, 0x4c, 0x44}; -const uint8_t HuffDecoderCommon::table1_415_emit_[67] = { - 0x4c, 0x45, 0x4c, 0x46, 0x4c, 0x47, 0x4c, 0x48, 0x4c, 0x49, 0x4c, 0x4a, - 0x4c, 0x4b, 0x4c, 0x4c, 0x4d, 0x4c, 0x4e, 0x4c, 0x4f, 0x4c, 0x50, 0x4c, - 0x51, 0x4c, 0x52, 0x4c, 0x53, 0x4c, 0x54, 0x4c, 0x55, 0x4c, 0x56, 0x4c, - 0x57, 0x4c, 0x59, 0x4c, 0x6a, 0x4c, 0x6b, 0x4c, 0x71, 0x4c, 0x76, 0x4c, - 0x77, 0x4c, 0x78, 0x4c, 0x79, 0x4c, 0x7a, 0x4c, 0x26, 0x4c, 0x2a, 0x4c, - 0x2c, 0x4c, 0x3b, 0x4c, 0x58, 0x4c, 0x5a}; -const uint16_t HuffDecoderCommon::table1_415_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x03de, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_416_emit_[16] = { - 0x4d, 0x30, 0x4d, 0x31, 0x4d, 0x32, 0x4d, 0x61, - 0x4d, 0x63, 0x4d, 0x65, 0x4d, 0x69, 0x4d, 0x6f}; -const uint8_t HuffDecoderCommon::table1_417_emit_[28] = { - 0x4d, 0x73, 0x4d, 0x74, 0x4d, 0x20, 0x4d, 0x25, 0x4d, 0x2d, - 0x4d, 0x2e, 0x4d, 0x2f, 0x4d, 0x33, 0x4d, 0x34, 0x4d, 0x35, - 0x4d, 0x36, 0x4d, 0x37, 0x4d, 0x38, 0x4d, 0x39}; -const uint8_t HuffDecoderCommon::table1_418_emit_[36] = { - 0x4d, 0x3d, 0x4d, 0x41, 0x4d, 0x5f, 0x4d, 0x62, 0x4d, 0x64, 0x4d, 0x66, - 0x4d, 0x67, 0x4d, 0x68, 0x4d, 0x6c, 0x4d, 0x6d, 0x4d, 0x6e, 0x4d, 0x70, - 0x4d, 0x72, 0x4d, 0x75, 0x4d, 0x3a, 0x4d, 0x42, 0x4d, 0x43, 0x4d, 0x44}; -const uint8_t HuffDecoderCommon::table1_419_emit_[67] = { - 0x4d, 0x45, 0x4d, 0x46, 0x4d, 0x47, 0x4d, 0x48, 0x4d, 0x49, 0x4d, 0x4a, - 0x4d, 0x4b, 0x4d, 0x4c, 0x4d, 0x4d, 0x4e, 0x4d, 0x4f, 0x4d, 0x50, 0x4d, - 0x51, 0x4d, 0x52, 0x4d, 0x53, 0x4d, 0x54, 0x4d, 0x55, 0x4d, 0x56, 0x4d, - 0x57, 0x4d, 0x59, 0x4d, 0x6a, 0x4d, 0x6b, 0x4d, 0x71, 0x4d, 0x76, 0x4d, - 0x77, 0x4d, 0x78, 0x4d, 0x79, 0x4d, 0x7a, 0x4d, 0x26, 0x4d, 0x2a, 0x4d, - 0x2c, 0x4d, 0x3b, 0x4d, 0x58, 0x4d, 0x5a}; -const uint16_t HuffDecoderCommon::table1_419_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x045e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_420_emit_[16] = { - 0x4e, 0x30, 0x4e, 0x31, 0x4e, 0x32, 0x4e, 0x61, - 0x4e, 0x63, 0x4e, 0x65, 0x4e, 0x69, 0x4e, 0x6f}; -const uint8_t HuffDecoderCommon::table1_421_emit_[28] = { - 0x4e, 0x73, 0x4e, 0x74, 0x4e, 0x20, 0x4e, 0x25, 0x4e, 0x2d, - 0x4e, 0x2e, 0x4e, 0x2f, 0x4e, 0x33, 0x4e, 0x34, 0x4e, 0x35, - 0x4e, 0x36, 0x4e, 0x37, 0x4e, 0x38, 0x4e, 0x39}; -const uint8_t HuffDecoderCommon::table1_422_emit_[36] = { - 0x4e, 0x3d, 0x4e, 0x41, 0x4e, 0x5f, 0x4e, 0x62, 0x4e, 0x64, 0x4e, 0x66, - 0x4e, 0x67, 0x4e, 0x68, 0x4e, 0x6c, 0x4e, 0x6d, 0x4e, 0x6e, 0x4e, 0x70, - 0x4e, 0x72, 0x4e, 0x75, 0x4e, 0x3a, 0x4e, 0x42, 0x4e, 0x43, 0x4e, 0x44}; -const uint8_t HuffDecoderCommon::table1_423_emit_[67] = { - 0x4e, 0x45, 0x4e, 0x46, 0x4e, 0x47, 0x4e, 0x48, 0x4e, 0x49, 0x4e, 0x4a, - 0x4e, 0x4b, 0x4e, 0x4c, 0x4e, 0x4d, 0x4e, 0x4e, 0x4f, 0x4e, 0x50, 0x4e, - 0x51, 0x4e, 0x52, 0x4e, 0x53, 0x4e, 0x54, 0x4e, 0x55, 0x4e, 0x56, 0x4e, - 0x57, 0x4e, 0x59, 0x4e, 0x6a, 0x4e, 0x6b, 0x4e, 0x71, 0x4e, 0x76, 0x4e, - 0x77, 0x4e, 0x78, 0x4e, 0x79, 0x4e, 0x7a, 0x4e, 0x26, 0x4e, 0x2a, 0x4e, - 0x2c, 0x4e, 0x3b, 0x4e, 0x58, 0x4e, 0x5a}; -const uint16_t HuffDecoderCommon::table1_423_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x04de, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_424_emit_[16] = { - 0x4f, 0x30, 0x4f, 0x31, 0x4f, 0x32, 0x4f, 0x61, - 0x4f, 0x63, 0x4f, 0x65, 0x4f, 0x69, 0x4f, 0x6f}; -const uint8_t HuffDecoderCommon::table1_425_emit_[28] = { - 0x4f, 0x73, 0x4f, 0x74, 0x4f, 0x20, 0x4f, 0x25, 0x4f, 0x2d, - 0x4f, 0x2e, 0x4f, 0x2f, 0x4f, 0x33, 0x4f, 0x34, 0x4f, 0x35, - 0x4f, 0x36, 0x4f, 0x37, 0x4f, 0x38, 0x4f, 0x39}; -const uint8_t HuffDecoderCommon::table1_426_emit_[36] = { - 0x4f, 0x3d, 0x4f, 0x41, 0x4f, 0x5f, 0x4f, 0x62, 0x4f, 0x64, 0x4f, 0x66, - 0x4f, 0x67, 0x4f, 0x68, 0x4f, 0x6c, 0x4f, 0x6d, 0x4f, 0x6e, 0x4f, 0x70, - 0x4f, 0x72, 0x4f, 0x75, 0x4f, 0x3a, 0x4f, 0x42, 0x4f, 0x43, 0x4f, 0x44}; -const uint8_t HuffDecoderCommon::table1_427_emit_[67] = { - 0x4f, 0x45, 0x4f, 0x46, 0x4f, 0x47, 0x4f, 0x48, 0x4f, 0x49, 0x4f, 0x4a, - 0x4f, 0x4b, 0x4f, 0x4c, 0x4f, 0x4d, 0x4f, 0x4e, 0x4f, 0x4f, 0x50, 0x4f, - 0x51, 0x4f, 0x52, 0x4f, 0x53, 0x4f, 0x54, 0x4f, 0x55, 0x4f, 0x56, 0x4f, - 0x57, 0x4f, 0x59, 0x4f, 0x6a, 0x4f, 0x6b, 0x4f, 0x71, 0x4f, 0x76, 0x4f, - 0x77, 0x4f, 0x78, 0x4f, 0x79, 0x4f, 0x7a, 0x4f, 0x26, 0x4f, 0x2a, 0x4f, - 0x2c, 0x4f, 0x3b, 0x4f, 0x58, 0x4f, 0x5a}; -const uint16_t HuffDecoderCommon::table1_427_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x055e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_428_emit_[16] = { - 0x50, 0x30, 0x50, 0x31, 0x50, 0x32, 0x50, 0x61, - 0x50, 0x63, 0x50, 0x65, 0x50, 0x69, 0x50, 0x6f}; -const uint8_t HuffDecoderCommon::table1_429_emit_[28] = { - 0x50, 0x73, 0x50, 0x74, 0x50, 0x20, 0x50, 0x25, 0x50, 0x2d, - 0x50, 0x2e, 0x50, 0x2f, 0x50, 0x33, 0x50, 0x34, 0x50, 0x35, - 0x50, 0x36, 0x50, 0x37, 0x50, 0x38, 0x50, 0x39}; -const uint8_t HuffDecoderCommon::table1_430_emit_[36] = { - 0x50, 0x3d, 0x50, 0x41, 0x50, 0x5f, 0x50, 0x62, 0x50, 0x64, 0x50, 0x66, - 0x50, 0x67, 0x50, 0x68, 0x50, 0x6c, 0x50, 0x6d, 0x50, 0x6e, 0x50, 0x70, - 0x50, 0x72, 0x50, 0x75, 0x50, 0x3a, 0x50, 0x42, 0x50, 0x43, 0x50, 0x44}; -const uint8_t HuffDecoderCommon::table1_431_emit_[67] = { - 0x50, 0x45, 0x50, 0x46, 0x50, 0x47, 0x50, 0x48, 0x50, 0x49, 0x50, 0x4a, - 0x50, 0x4b, 0x50, 0x4c, 0x50, 0x4d, 0x50, 0x4e, 0x50, 0x4f, 0x50, 0x50, - 0x51, 0x50, 0x52, 0x50, 0x53, 0x50, 0x54, 0x50, 0x55, 0x50, 0x56, 0x50, - 0x57, 0x50, 0x59, 0x50, 0x6a, 0x50, 0x6b, 0x50, 0x71, 0x50, 0x76, 0x50, - 0x77, 0x50, 0x78, 0x50, 0x79, 0x50, 0x7a, 0x50, 0x26, 0x50, 0x2a, 0x50, - 0x2c, 0x50, 0x3b, 0x50, 0x58, 0x50, 0x5a}; -const uint16_t HuffDecoderCommon::table1_431_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x05de, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_432_emit_[16] = { - 0x51, 0x30, 0x51, 0x31, 0x51, 0x32, 0x51, 0x61, - 0x51, 0x63, 0x51, 0x65, 0x51, 0x69, 0x51, 0x6f}; -const uint8_t HuffDecoderCommon::table1_433_emit_[28] = { - 0x51, 0x73, 0x51, 0x74, 0x51, 0x20, 0x51, 0x25, 0x51, 0x2d, - 0x51, 0x2e, 0x51, 0x2f, 0x51, 0x33, 0x51, 0x34, 0x51, 0x35, - 0x51, 0x36, 0x51, 0x37, 0x51, 0x38, 0x51, 0x39}; -const uint8_t HuffDecoderCommon::table1_434_emit_[36] = { - 0x51, 0x3d, 0x51, 0x41, 0x51, 0x5f, 0x51, 0x62, 0x51, 0x64, 0x51, 0x66, - 0x51, 0x67, 0x51, 0x68, 0x51, 0x6c, 0x51, 0x6d, 0x51, 0x6e, 0x51, 0x70, - 0x51, 0x72, 0x51, 0x75, 0x51, 0x3a, 0x51, 0x42, 0x51, 0x43, 0x51, 0x44}; -const uint8_t HuffDecoderCommon::table1_435_emit_[67] = { - 0x51, 0x45, 0x51, 0x46, 0x51, 0x47, 0x51, 0x48, 0x51, 0x49, 0x51, 0x4a, - 0x51, 0x4b, 0x51, 0x4c, 0x51, 0x4d, 0x51, 0x4e, 0x51, 0x4f, 0x51, 0x50, - 0x51, 0x51, 0x52, 0x51, 0x53, 0x51, 0x54, 0x51, 0x55, 0x51, 0x56, 0x51, - 0x57, 0x51, 0x59, 0x51, 0x6a, 0x51, 0x6b, 0x51, 0x71, 0x51, 0x76, 0x51, - 0x77, 0x51, 0x78, 0x51, 0x79, 0x51, 0x7a, 0x51, 0x26, 0x51, 0x2a, 0x51, - 0x2c, 0x51, 0x3b, 0x51, 0x58, 0x51, 0x5a}; -const uint16_t HuffDecoderCommon::table1_435_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x065e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_436_emit_[16] = { - 0x52, 0x30, 0x52, 0x31, 0x52, 0x32, 0x52, 0x61, - 0x52, 0x63, 0x52, 0x65, 0x52, 0x69, 0x52, 0x6f}; -const uint8_t HuffDecoderCommon::table1_437_emit_[28] = { - 0x52, 0x73, 0x52, 0x74, 0x52, 0x20, 0x52, 0x25, 0x52, 0x2d, - 0x52, 0x2e, 0x52, 0x2f, 0x52, 0x33, 0x52, 0x34, 0x52, 0x35, - 0x52, 0x36, 0x52, 0x37, 0x52, 0x38, 0x52, 0x39}; -const uint8_t HuffDecoderCommon::table1_438_emit_[36] = { - 0x52, 0x3d, 0x52, 0x41, 0x52, 0x5f, 0x52, 0x62, 0x52, 0x64, 0x52, 0x66, - 0x52, 0x67, 0x52, 0x68, 0x52, 0x6c, 0x52, 0x6d, 0x52, 0x6e, 0x52, 0x70, - 0x52, 0x72, 0x52, 0x75, 0x52, 0x3a, 0x52, 0x42, 0x52, 0x43, 0x52, 0x44}; -const uint8_t HuffDecoderCommon::table1_439_emit_[67] = { - 0x52, 0x45, 0x52, 0x46, 0x52, 0x47, 0x52, 0x48, 0x52, 0x49, 0x52, 0x4a, - 0x52, 0x4b, 0x52, 0x4c, 0x52, 0x4d, 0x52, 0x4e, 0x52, 0x4f, 0x52, 0x50, - 0x52, 0x51, 0x52, 0x52, 0x53, 0x52, 0x54, 0x52, 0x55, 0x52, 0x56, 0x52, - 0x57, 0x52, 0x59, 0x52, 0x6a, 0x52, 0x6b, 0x52, 0x71, 0x52, 0x76, 0x52, - 0x77, 0x52, 0x78, 0x52, 0x79, 0x52, 0x7a, 0x52, 0x26, 0x52, 0x2a, 0x52, - 0x2c, 0x52, 0x3b, 0x52, 0x58, 0x52, 0x5a}; -const uint16_t HuffDecoderCommon::table1_439_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x06de, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_440_emit_[16] = { - 0x53, 0x30, 0x53, 0x31, 0x53, 0x32, 0x53, 0x61, - 0x53, 0x63, 0x53, 0x65, 0x53, 0x69, 0x53, 0x6f}; -const uint8_t HuffDecoderCommon::table1_441_emit_[28] = { - 0x53, 0x73, 0x53, 0x74, 0x53, 0x20, 0x53, 0x25, 0x53, 0x2d, - 0x53, 0x2e, 0x53, 0x2f, 0x53, 0x33, 0x53, 0x34, 0x53, 0x35, - 0x53, 0x36, 0x53, 0x37, 0x53, 0x38, 0x53, 0x39}; -const uint8_t HuffDecoderCommon::table1_442_emit_[36] = { - 0x53, 0x3d, 0x53, 0x41, 0x53, 0x5f, 0x53, 0x62, 0x53, 0x64, 0x53, 0x66, - 0x53, 0x67, 0x53, 0x68, 0x53, 0x6c, 0x53, 0x6d, 0x53, 0x6e, 0x53, 0x70, - 0x53, 0x72, 0x53, 0x75, 0x53, 0x3a, 0x53, 0x42, 0x53, 0x43, 0x53, 0x44}; -const uint8_t HuffDecoderCommon::table1_443_emit_[67] = { - 0x53, 0x45, 0x53, 0x46, 0x53, 0x47, 0x53, 0x48, 0x53, 0x49, 0x53, 0x4a, - 0x53, 0x4b, 0x53, 0x4c, 0x53, 0x4d, 0x53, 0x4e, 0x53, 0x4f, 0x53, 0x50, - 0x53, 0x51, 0x53, 0x52, 0x53, 0x53, 0x54, 0x53, 0x55, 0x53, 0x56, 0x53, - 0x57, 0x53, 0x59, 0x53, 0x6a, 0x53, 0x6b, 0x53, 0x71, 0x53, 0x76, 0x53, - 0x77, 0x53, 0x78, 0x53, 0x79, 0x53, 0x7a, 0x53, 0x26, 0x53, 0x2a, 0x53, - 0x2c, 0x53, 0x3b, 0x53, 0x58, 0x53, 0x5a}; -const uint16_t HuffDecoderCommon::table1_443_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x075e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_444_emit_[16] = { - 0x54, 0x30, 0x54, 0x31, 0x54, 0x32, 0x54, 0x61, - 0x54, 0x63, 0x54, 0x65, 0x54, 0x69, 0x54, 0x6f}; -const uint8_t HuffDecoderCommon::table1_445_emit_[28] = { - 0x54, 0x73, 0x54, 0x74, 0x54, 0x20, 0x54, 0x25, 0x54, 0x2d, - 0x54, 0x2e, 0x54, 0x2f, 0x54, 0x33, 0x54, 0x34, 0x54, 0x35, - 0x54, 0x36, 0x54, 0x37, 0x54, 0x38, 0x54, 0x39}; -const uint8_t HuffDecoderCommon::table1_446_emit_[36] = { - 0x54, 0x3d, 0x54, 0x41, 0x54, 0x5f, 0x54, 0x62, 0x54, 0x64, 0x54, 0x66, - 0x54, 0x67, 0x54, 0x68, 0x54, 0x6c, 0x54, 0x6d, 0x54, 0x6e, 0x54, 0x70, - 0x54, 0x72, 0x54, 0x75, 0x54, 0x3a, 0x54, 0x42, 0x54, 0x43, 0x54, 0x44}; -const uint8_t HuffDecoderCommon::table1_447_emit_[67] = { - 0x54, 0x45, 0x54, 0x46, 0x54, 0x47, 0x54, 0x48, 0x54, 0x49, 0x54, 0x4a, - 0x54, 0x4b, 0x54, 0x4c, 0x54, 0x4d, 0x54, 0x4e, 0x54, 0x4f, 0x54, 0x50, - 0x54, 0x51, 0x54, 0x52, 0x54, 0x53, 0x54, 0x54, 0x55, 0x54, 0x56, 0x54, - 0x57, 0x54, 0x59, 0x54, 0x6a, 0x54, 0x6b, 0x54, 0x71, 0x54, 0x76, 0x54, - 0x77, 0x54, 0x78, 0x54, 0x79, 0x54, 0x7a, 0x54, 0x26, 0x54, 0x2a, 0x54, - 0x2c, 0x54, 0x3b, 0x54, 0x58, 0x54, 0x5a}; -const uint16_t HuffDecoderCommon::table1_447_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x07de, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_448_emit_[16] = { - 0x55, 0x30, 0x55, 0x31, 0x55, 0x32, 0x55, 0x61, - 0x55, 0x63, 0x55, 0x65, 0x55, 0x69, 0x55, 0x6f}; -const uint8_t HuffDecoderCommon::table1_449_emit_[28] = { - 0x55, 0x73, 0x55, 0x74, 0x55, 0x20, 0x55, 0x25, 0x55, 0x2d, - 0x55, 0x2e, 0x55, 0x2f, 0x55, 0x33, 0x55, 0x34, 0x55, 0x35, - 0x55, 0x36, 0x55, 0x37, 0x55, 0x38, 0x55, 0x39}; -const uint8_t HuffDecoderCommon::table1_450_emit_[36] = { - 0x55, 0x3d, 0x55, 0x41, 0x55, 0x5f, 0x55, 0x62, 0x55, 0x64, 0x55, 0x66, - 0x55, 0x67, 0x55, 0x68, 0x55, 0x6c, 0x55, 0x6d, 0x55, 0x6e, 0x55, 0x70, - 0x55, 0x72, 0x55, 0x75, 0x55, 0x3a, 0x55, 0x42, 0x55, 0x43, 0x55, 0x44}; -const uint8_t HuffDecoderCommon::table1_451_emit_[67] = { - 0x55, 0x45, 0x55, 0x46, 0x55, 0x47, 0x55, 0x48, 0x55, 0x49, 0x55, 0x4a, - 0x55, 0x4b, 0x55, 0x4c, 0x55, 0x4d, 0x55, 0x4e, 0x55, 0x4f, 0x55, 0x50, - 0x55, 0x51, 0x55, 0x52, 0x55, 0x53, 0x55, 0x54, 0x55, 0x55, 0x56, 0x55, - 0x57, 0x55, 0x59, 0x55, 0x6a, 0x55, 0x6b, 0x55, 0x71, 0x55, 0x76, 0x55, - 0x77, 0x55, 0x78, 0x55, 0x79, 0x55, 0x7a, 0x55, 0x26, 0x55, 0x2a, 0x55, - 0x2c, 0x55, 0x3b, 0x55, 0x58, 0x55, 0x5a}; -const uint16_t HuffDecoderCommon::table1_451_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x085e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_452_emit_[16] = { - 0x56, 0x30, 0x56, 0x31, 0x56, 0x32, 0x56, 0x61, - 0x56, 0x63, 0x56, 0x65, 0x56, 0x69, 0x56, 0x6f}; -const uint8_t HuffDecoderCommon::table1_453_emit_[28] = { - 0x56, 0x73, 0x56, 0x74, 0x56, 0x20, 0x56, 0x25, 0x56, 0x2d, - 0x56, 0x2e, 0x56, 0x2f, 0x56, 0x33, 0x56, 0x34, 0x56, 0x35, - 0x56, 0x36, 0x56, 0x37, 0x56, 0x38, 0x56, 0x39}; -const uint8_t HuffDecoderCommon::table1_454_emit_[36] = { - 0x56, 0x3d, 0x56, 0x41, 0x56, 0x5f, 0x56, 0x62, 0x56, 0x64, 0x56, 0x66, - 0x56, 0x67, 0x56, 0x68, 0x56, 0x6c, 0x56, 0x6d, 0x56, 0x6e, 0x56, 0x70, - 0x56, 0x72, 0x56, 0x75, 0x56, 0x3a, 0x56, 0x42, 0x56, 0x43, 0x56, 0x44}; -const uint8_t HuffDecoderCommon::table1_455_emit_[67] = { - 0x56, 0x45, 0x56, 0x46, 0x56, 0x47, 0x56, 0x48, 0x56, 0x49, 0x56, 0x4a, - 0x56, 0x4b, 0x56, 0x4c, 0x56, 0x4d, 0x56, 0x4e, 0x56, 0x4f, 0x56, 0x50, - 0x56, 0x51, 0x56, 0x52, 0x56, 0x53, 0x56, 0x54, 0x56, 0x55, 0x56, 0x56, - 0x57, 0x56, 0x59, 0x56, 0x6a, 0x56, 0x6b, 0x56, 0x71, 0x56, 0x76, 0x56, - 0x77, 0x56, 0x78, 0x56, 0x79, 0x56, 0x7a, 0x56, 0x26, 0x56, 0x2a, 0x56, - 0x2c, 0x56, 0x3b, 0x56, 0x58, 0x56, 0x5a}; -const uint16_t HuffDecoderCommon::table1_455_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x08de, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_456_emit_[16] = { - 0x57, 0x30, 0x57, 0x31, 0x57, 0x32, 0x57, 0x61, - 0x57, 0x63, 0x57, 0x65, 0x57, 0x69, 0x57, 0x6f}; -const uint8_t HuffDecoderCommon::table1_457_emit_[28] = { - 0x57, 0x73, 0x57, 0x74, 0x57, 0x20, 0x57, 0x25, 0x57, 0x2d, - 0x57, 0x2e, 0x57, 0x2f, 0x57, 0x33, 0x57, 0x34, 0x57, 0x35, - 0x57, 0x36, 0x57, 0x37, 0x57, 0x38, 0x57, 0x39}; -const uint8_t HuffDecoderCommon::table1_458_emit_[36] = { - 0x57, 0x3d, 0x57, 0x41, 0x57, 0x5f, 0x57, 0x62, 0x57, 0x64, 0x57, 0x66, - 0x57, 0x67, 0x57, 0x68, 0x57, 0x6c, 0x57, 0x6d, 0x57, 0x6e, 0x57, 0x70, - 0x57, 0x72, 0x57, 0x75, 0x57, 0x3a, 0x57, 0x42, 0x57, 0x43, 0x57, 0x44}; -const uint8_t HuffDecoderCommon::table1_459_emit_[67] = { - 0x57, 0x45, 0x57, 0x46, 0x57, 0x47, 0x57, 0x48, 0x57, 0x49, 0x57, 0x4a, - 0x57, 0x4b, 0x57, 0x4c, 0x57, 0x4d, 0x57, 0x4e, 0x57, 0x4f, 0x57, 0x50, - 0x57, 0x51, 0x57, 0x52, 0x57, 0x53, 0x57, 0x54, 0x57, 0x55, 0x57, 0x56, - 0x57, 0x57, 0x59, 0x57, 0x6a, 0x57, 0x6b, 0x57, 0x71, 0x57, 0x76, 0x57, - 0x77, 0x57, 0x78, 0x57, 0x79, 0x57, 0x7a, 0x57, 0x26, 0x57, 0x2a, 0x57, - 0x2c, 0x57, 0x3b, 0x57, 0x58, 0x57, 0x5a}; -const uint16_t HuffDecoderCommon::table1_459_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x095e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_460_emit_[16] = { - 0x59, 0x30, 0x59, 0x31, 0x59, 0x32, 0x59, 0x61, - 0x59, 0x63, 0x59, 0x65, 0x59, 0x69, 0x59, 0x6f}; -const uint8_t HuffDecoderCommon::table1_461_emit_[28] = { - 0x59, 0x73, 0x59, 0x74, 0x59, 0x20, 0x59, 0x25, 0x59, 0x2d, - 0x59, 0x2e, 0x59, 0x2f, 0x59, 0x33, 0x59, 0x34, 0x59, 0x35, - 0x59, 0x36, 0x59, 0x37, 0x59, 0x38, 0x59, 0x39}; -const uint8_t HuffDecoderCommon::table1_462_emit_[36] = { - 0x59, 0x3d, 0x59, 0x41, 0x59, 0x5f, 0x59, 0x62, 0x59, 0x64, 0x59, 0x66, - 0x59, 0x67, 0x59, 0x68, 0x59, 0x6c, 0x59, 0x6d, 0x59, 0x6e, 0x59, 0x70, - 0x59, 0x72, 0x59, 0x75, 0x59, 0x3a, 0x59, 0x42, 0x59, 0x43, 0x59, 0x44}; -const uint8_t HuffDecoderCommon::table1_463_emit_[67] = { - 0x59, 0x45, 0x59, 0x46, 0x59, 0x47, 0x59, 0x48, 0x59, 0x49, 0x59, 0x4a, - 0x59, 0x4b, 0x59, 0x4c, 0x59, 0x4d, 0x59, 0x4e, 0x59, 0x4f, 0x59, 0x50, - 0x59, 0x51, 0x59, 0x52, 0x59, 0x53, 0x59, 0x54, 0x59, 0x55, 0x59, 0x56, - 0x59, 0x57, 0x59, 0x59, 0x6a, 0x59, 0x6b, 0x59, 0x71, 0x59, 0x76, 0x59, - 0x77, 0x59, 0x78, 0x59, 0x79, 0x59, 0x7a, 0x59, 0x26, 0x59, 0x2a, 0x59, - 0x2c, 0x59, 0x3b, 0x59, 0x58, 0x59, 0x5a}; -const uint16_t HuffDecoderCommon::table1_463_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x09de, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_464_emit_[16] = { - 0x6a, 0x30, 0x6a, 0x31, 0x6a, 0x32, 0x6a, 0x61, - 0x6a, 0x63, 0x6a, 0x65, 0x6a, 0x69, 0x6a, 0x6f}; -const uint8_t HuffDecoderCommon::table1_465_emit_[28] = { - 0x6a, 0x73, 0x6a, 0x74, 0x6a, 0x20, 0x6a, 0x25, 0x6a, 0x2d, - 0x6a, 0x2e, 0x6a, 0x2f, 0x6a, 0x33, 0x6a, 0x34, 0x6a, 0x35, - 0x6a, 0x36, 0x6a, 0x37, 0x6a, 0x38, 0x6a, 0x39}; -const uint8_t HuffDecoderCommon::table1_466_emit_[36] = { - 0x6a, 0x3d, 0x6a, 0x41, 0x6a, 0x5f, 0x6a, 0x62, 0x6a, 0x64, 0x6a, 0x66, - 0x6a, 0x67, 0x6a, 0x68, 0x6a, 0x6c, 0x6a, 0x6d, 0x6a, 0x6e, 0x6a, 0x70, - 0x6a, 0x72, 0x6a, 0x75, 0x6a, 0x3a, 0x6a, 0x42, 0x6a, 0x43, 0x6a, 0x44}; -const uint8_t HuffDecoderCommon::table1_467_emit_[67] = { - 0x6a, 0x45, 0x6a, 0x46, 0x6a, 0x47, 0x6a, 0x48, 0x6a, 0x49, 0x6a, 0x4a, - 0x6a, 0x4b, 0x6a, 0x4c, 0x6a, 0x4d, 0x6a, 0x4e, 0x6a, 0x4f, 0x6a, 0x50, - 0x6a, 0x51, 0x6a, 0x52, 0x6a, 0x53, 0x6a, 0x54, 0x6a, 0x55, 0x6a, 0x56, - 0x6a, 0x57, 0x6a, 0x59, 0x6a, 0x6a, 0x6b, 0x6a, 0x71, 0x6a, 0x76, 0x6a, - 0x77, 0x6a, 0x78, 0x6a, 0x79, 0x6a, 0x7a, 0x6a, 0x26, 0x6a, 0x2a, 0x6a, - 0x2c, 0x6a, 0x3b, 0x6a, 0x58, 0x6a, 0x5a}; -const uint16_t HuffDecoderCommon::table1_467_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a5e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_468_emit_[16] = { - 0x6b, 0x30, 0x6b, 0x31, 0x6b, 0x32, 0x6b, 0x61, - 0x6b, 0x63, 0x6b, 0x65, 0x6b, 0x69, 0x6b, 0x6f}; -const uint8_t HuffDecoderCommon::table1_469_emit_[28] = { - 0x6b, 0x73, 0x6b, 0x74, 0x6b, 0x20, 0x6b, 0x25, 0x6b, 0x2d, - 0x6b, 0x2e, 0x6b, 0x2f, 0x6b, 0x33, 0x6b, 0x34, 0x6b, 0x35, - 0x6b, 0x36, 0x6b, 0x37, 0x6b, 0x38, 0x6b, 0x39}; -const uint8_t HuffDecoderCommon::table1_470_emit_[36] = { - 0x6b, 0x3d, 0x6b, 0x41, 0x6b, 0x5f, 0x6b, 0x62, 0x6b, 0x64, 0x6b, 0x66, - 0x6b, 0x67, 0x6b, 0x68, 0x6b, 0x6c, 0x6b, 0x6d, 0x6b, 0x6e, 0x6b, 0x70, - 0x6b, 0x72, 0x6b, 0x75, 0x6b, 0x3a, 0x6b, 0x42, 0x6b, 0x43, 0x6b, 0x44}; -const uint8_t HuffDecoderCommon::table1_471_emit_[67] = { - 0x6b, 0x45, 0x6b, 0x46, 0x6b, 0x47, 0x6b, 0x48, 0x6b, 0x49, 0x6b, 0x4a, - 0x6b, 0x4b, 0x6b, 0x4c, 0x6b, 0x4d, 0x6b, 0x4e, 0x6b, 0x4f, 0x6b, 0x50, - 0x6b, 0x51, 0x6b, 0x52, 0x6b, 0x53, 0x6b, 0x54, 0x6b, 0x55, 0x6b, 0x56, - 0x6b, 0x57, 0x6b, 0x59, 0x6b, 0x6a, 0x6b, 0x6b, 0x71, 0x6b, 0x76, 0x6b, - 0x77, 0x6b, 0x78, 0x6b, 0x79, 0x6b, 0x7a, 0x6b, 0x26, 0x6b, 0x2a, 0x6b, - 0x2c, 0x6b, 0x3b, 0x6b, 0x58, 0x6b, 0x5a}; -const uint16_t HuffDecoderCommon::table1_471_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0ade, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_472_emit_[16] = { - 0x71, 0x30, 0x71, 0x31, 0x71, 0x32, 0x71, 0x61, - 0x71, 0x63, 0x71, 0x65, 0x71, 0x69, 0x71, 0x6f}; -const uint8_t HuffDecoderCommon::table1_473_emit_[28] = { - 0x71, 0x73, 0x71, 0x74, 0x71, 0x20, 0x71, 0x25, 0x71, 0x2d, - 0x71, 0x2e, 0x71, 0x2f, 0x71, 0x33, 0x71, 0x34, 0x71, 0x35, - 0x71, 0x36, 0x71, 0x37, 0x71, 0x38, 0x71, 0x39}; -const uint8_t HuffDecoderCommon::table1_474_emit_[36] = { - 0x71, 0x3d, 0x71, 0x41, 0x71, 0x5f, 0x71, 0x62, 0x71, 0x64, 0x71, 0x66, - 0x71, 0x67, 0x71, 0x68, 0x71, 0x6c, 0x71, 0x6d, 0x71, 0x6e, 0x71, 0x70, - 0x71, 0x72, 0x71, 0x75, 0x71, 0x3a, 0x71, 0x42, 0x71, 0x43, 0x71, 0x44}; -const uint8_t HuffDecoderCommon::table1_475_emit_[67] = { - 0x71, 0x45, 0x71, 0x46, 0x71, 0x47, 0x71, 0x48, 0x71, 0x49, 0x71, 0x4a, - 0x71, 0x4b, 0x71, 0x4c, 0x71, 0x4d, 0x71, 0x4e, 0x71, 0x4f, 0x71, 0x50, - 0x71, 0x51, 0x71, 0x52, 0x71, 0x53, 0x71, 0x54, 0x71, 0x55, 0x71, 0x56, - 0x71, 0x57, 0x71, 0x59, 0x71, 0x6a, 0x71, 0x6b, 0x71, 0x71, 0x76, 0x71, - 0x77, 0x71, 0x78, 0x71, 0x79, 0x71, 0x7a, 0x71, 0x26, 0x71, 0x2a, 0x71, - 0x2c, 0x71, 0x3b, 0x71, 0x58, 0x71, 0x5a}; -const uint16_t HuffDecoderCommon::table1_475_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0b1e, 0x0b5e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_476_emit_[16] = { - 0x76, 0x30, 0x76, 0x31, 0x76, 0x32, 0x76, 0x61, - 0x76, 0x63, 0x76, 0x65, 0x76, 0x69, 0x76, 0x6f}; -const uint8_t HuffDecoderCommon::table1_477_emit_[28] = { - 0x76, 0x73, 0x76, 0x74, 0x76, 0x20, 0x76, 0x25, 0x76, 0x2d, - 0x76, 0x2e, 0x76, 0x2f, 0x76, 0x33, 0x76, 0x34, 0x76, 0x35, - 0x76, 0x36, 0x76, 0x37, 0x76, 0x38, 0x76, 0x39}; -const uint8_t HuffDecoderCommon::table1_478_emit_[36] = { - 0x76, 0x3d, 0x76, 0x41, 0x76, 0x5f, 0x76, 0x62, 0x76, 0x64, 0x76, 0x66, - 0x76, 0x67, 0x76, 0x68, 0x76, 0x6c, 0x76, 0x6d, 0x76, 0x6e, 0x76, 0x70, - 0x76, 0x72, 0x76, 0x75, 0x76, 0x3a, 0x76, 0x42, 0x76, 0x43, 0x76, 0x44}; -const uint8_t HuffDecoderCommon::table1_479_emit_[67] = { - 0x76, 0x45, 0x76, 0x46, 0x76, 0x47, 0x76, 0x48, 0x76, 0x49, 0x76, 0x4a, - 0x76, 0x4b, 0x76, 0x4c, 0x76, 0x4d, 0x76, 0x4e, 0x76, 0x4f, 0x76, 0x50, - 0x76, 0x51, 0x76, 0x52, 0x76, 0x53, 0x76, 0x54, 0x76, 0x55, 0x76, 0x56, - 0x76, 0x57, 0x76, 0x59, 0x76, 0x6a, 0x76, 0x6b, 0x76, 0x71, 0x76, 0x76, - 0x77, 0x76, 0x78, 0x76, 0x79, 0x76, 0x7a, 0x76, 0x26, 0x76, 0x2a, 0x76, - 0x2c, 0x76, 0x3b, 0x76, 0x58, 0x76, 0x5a}; -const uint16_t HuffDecoderCommon::table1_479_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0b1e, 0x0b9e, 0x0bde, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_480_emit_[16] = { - 0x77, 0x30, 0x77, 0x31, 0x77, 0x32, 0x77, 0x61, - 0x77, 0x63, 0x77, 0x65, 0x77, 0x69, 0x77, 0x6f}; -const uint8_t HuffDecoderCommon::table1_481_emit_[28] = { - 0x77, 0x73, 0x77, 0x74, 0x77, 0x20, 0x77, 0x25, 0x77, 0x2d, - 0x77, 0x2e, 0x77, 0x2f, 0x77, 0x33, 0x77, 0x34, 0x77, 0x35, - 0x77, 0x36, 0x77, 0x37, 0x77, 0x38, 0x77, 0x39}; -const uint8_t HuffDecoderCommon::table1_482_emit_[36] = { - 0x77, 0x3d, 0x77, 0x41, 0x77, 0x5f, 0x77, 0x62, 0x77, 0x64, 0x77, 0x66, - 0x77, 0x67, 0x77, 0x68, 0x77, 0x6c, 0x77, 0x6d, 0x77, 0x6e, 0x77, 0x70, - 0x77, 0x72, 0x77, 0x75, 0x77, 0x3a, 0x77, 0x42, 0x77, 0x43, 0x77, 0x44}; -const uint8_t HuffDecoderCommon::table1_483_emit_[67] = { - 0x77, 0x45, 0x77, 0x46, 0x77, 0x47, 0x77, 0x48, 0x77, 0x49, 0x77, 0x4a, - 0x77, 0x4b, 0x77, 0x4c, 0x77, 0x4d, 0x77, 0x4e, 0x77, 0x4f, 0x77, 0x50, - 0x77, 0x51, 0x77, 0x52, 0x77, 0x53, 0x77, 0x54, 0x77, 0x55, 0x77, 0x56, - 0x77, 0x57, 0x77, 0x59, 0x77, 0x6a, 0x77, 0x6b, 0x77, 0x71, 0x77, 0x76, - 0x77, 0x77, 0x78, 0x77, 0x79, 0x77, 0x7a, 0x77, 0x26, 0x77, 0x2a, 0x77, - 0x2c, 0x77, 0x3b, 0x77, 0x58, 0x77, 0x5a}; -const uint16_t HuffDecoderCommon::table1_483_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0b1e, 0x0b9e, 0x0c1e, 0x0c5e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_484_emit_[16] = { - 0x78, 0x30, 0x78, 0x31, 0x78, 0x32, 0x78, 0x61, - 0x78, 0x63, 0x78, 0x65, 0x78, 0x69, 0x78, 0x6f}; -const uint8_t HuffDecoderCommon::table1_485_emit_[28] = { - 0x78, 0x73, 0x78, 0x74, 0x78, 0x20, 0x78, 0x25, 0x78, 0x2d, - 0x78, 0x2e, 0x78, 0x2f, 0x78, 0x33, 0x78, 0x34, 0x78, 0x35, - 0x78, 0x36, 0x78, 0x37, 0x78, 0x38, 0x78, 0x39}; -const uint8_t HuffDecoderCommon::table1_486_emit_[36] = { - 0x78, 0x3d, 0x78, 0x41, 0x78, 0x5f, 0x78, 0x62, 0x78, 0x64, 0x78, 0x66, - 0x78, 0x67, 0x78, 0x68, 0x78, 0x6c, 0x78, 0x6d, 0x78, 0x6e, 0x78, 0x70, - 0x78, 0x72, 0x78, 0x75, 0x78, 0x3a, 0x78, 0x42, 0x78, 0x43, 0x78, 0x44}; -const uint8_t HuffDecoderCommon::table1_487_emit_[67] = { - 0x78, 0x45, 0x78, 0x46, 0x78, 0x47, 0x78, 0x48, 0x78, 0x49, 0x78, 0x4a, - 0x78, 0x4b, 0x78, 0x4c, 0x78, 0x4d, 0x78, 0x4e, 0x78, 0x4f, 0x78, 0x50, - 0x78, 0x51, 0x78, 0x52, 0x78, 0x53, 0x78, 0x54, 0x78, 0x55, 0x78, 0x56, - 0x78, 0x57, 0x78, 0x59, 0x78, 0x6a, 0x78, 0x6b, 0x78, 0x71, 0x78, 0x76, - 0x78, 0x77, 0x78, 0x78, 0x79, 0x78, 0x7a, 0x78, 0x26, 0x78, 0x2a, 0x78, - 0x2c, 0x78, 0x3b, 0x78, 0x58, 0x78, 0x5a}; -const uint16_t HuffDecoderCommon::table1_487_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0b1e, 0x0b9e, 0x0c1e, 0x0c9e, 0x0cde, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_488_emit_[16] = { - 0x79, 0x30, 0x79, 0x31, 0x79, 0x32, 0x79, 0x61, - 0x79, 0x63, 0x79, 0x65, 0x79, 0x69, 0x79, 0x6f}; -const uint8_t HuffDecoderCommon::table1_489_emit_[28] = { - 0x79, 0x73, 0x79, 0x74, 0x79, 0x20, 0x79, 0x25, 0x79, 0x2d, - 0x79, 0x2e, 0x79, 0x2f, 0x79, 0x33, 0x79, 0x34, 0x79, 0x35, - 0x79, 0x36, 0x79, 0x37, 0x79, 0x38, 0x79, 0x39}; -const uint8_t HuffDecoderCommon::table1_490_emit_[36] = { - 0x79, 0x3d, 0x79, 0x41, 0x79, 0x5f, 0x79, 0x62, 0x79, 0x64, 0x79, 0x66, - 0x79, 0x67, 0x79, 0x68, 0x79, 0x6c, 0x79, 0x6d, 0x79, 0x6e, 0x79, 0x70, - 0x79, 0x72, 0x79, 0x75, 0x79, 0x3a, 0x79, 0x42, 0x79, 0x43, 0x79, 0x44}; -const uint8_t HuffDecoderCommon::table1_491_emit_[67] = { - 0x79, 0x45, 0x79, 0x46, 0x79, 0x47, 0x79, 0x48, 0x79, 0x49, 0x79, 0x4a, - 0x79, 0x4b, 0x79, 0x4c, 0x79, 0x4d, 0x79, 0x4e, 0x79, 0x4f, 0x79, 0x50, - 0x79, 0x51, 0x79, 0x52, 0x79, 0x53, 0x79, 0x54, 0x79, 0x55, 0x79, 0x56, - 0x79, 0x57, 0x79, 0x59, 0x79, 0x6a, 0x79, 0x6b, 0x79, 0x71, 0x79, 0x76, - 0x79, 0x77, 0x79, 0x78, 0x79, 0x79, 0x7a, 0x79, 0x26, 0x79, 0x2a, 0x79, - 0x2c, 0x79, 0x3b, 0x79, 0x58, 0x79, 0x5a}; -const uint16_t HuffDecoderCommon::table1_491_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0b1e, 0x0b9e, 0x0c1e, 0x0c9e, 0x0d1e, - 0x0d5e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_492_emit_[16] = { - 0x7a, 0x30, 0x7a, 0x31, 0x7a, 0x32, 0x7a, 0x61, - 0x7a, 0x63, 0x7a, 0x65, 0x7a, 0x69, 0x7a, 0x6f}; -const uint8_t HuffDecoderCommon::table1_493_emit_[28] = { - 0x7a, 0x73, 0x7a, 0x74, 0x7a, 0x20, 0x7a, 0x25, 0x7a, 0x2d, - 0x7a, 0x2e, 0x7a, 0x2f, 0x7a, 0x33, 0x7a, 0x34, 0x7a, 0x35, - 0x7a, 0x36, 0x7a, 0x37, 0x7a, 0x38, 0x7a, 0x39}; -const uint8_t HuffDecoderCommon::table1_494_emit_[36] = { - 0x7a, 0x3d, 0x7a, 0x41, 0x7a, 0x5f, 0x7a, 0x62, 0x7a, 0x64, 0x7a, 0x66, - 0x7a, 0x67, 0x7a, 0x68, 0x7a, 0x6c, 0x7a, 0x6d, 0x7a, 0x6e, 0x7a, 0x70, - 0x7a, 0x72, 0x7a, 0x75, 0x7a, 0x3a, 0x7a, 0x42, 0x7a, 0x43, 0x7a, 0x44}; -const uint8_t HuffDecoderCommon::table1_495_emit_[67] = { - 0x7a, 0x45, 0x7a, 0x46, 0x7a, 0x47, 0x7a, 0x48, 0x7a, 0x49, 0x7a, 0x4a, - 0x7a, 0x4b, 0x7a, 0x4c, 0x7a, 0x4d, 0x7a, 0x4e, 0x7a, 0x4f, 0x7a, 0x50, - 0x7a, 0x51, 0x7a, 0x52, 0x7a, 0x53, 0x7a, 0x54, 0x7a, 0x55, 0x7a, 0x56, - 0x7a, 0x57, 0x7a, 0x59, 0x7a, 0x6a, 0x7a, 0x6b, 0x7a, 0x71, 0x7a, 0x76, - 0x7a, 0x77, 0x7a, 0x78, 0x7a, 0x79, 0x7a, 0x7a, 0x26, 0x7a, 0x2a, 0x7a, - 0x2c, 0x7a, 0x3b, 0x7a, 0x58, 0x7a, 0x5a}; -const uint16_t HuffDecoderCommon::table1_495_inner_[35] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, 0x041e, - 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, 0x081e, 0x089e, - 0x091e, 0x099e, 0x0a1e, 0x0a9e, 0x0b1e, 0x0b9e, 0x0c1e, 0x0c9e, 0x0d1e, - 0x0d9e, 0x0ddf, 0x0e5f, 0x0edf, 0x0f5f, 0x0fdf, 0x105f, 0x0027}; -const uint8_t HuffDecoderCommon::table1_496_emit_[44] = { - 0x26, 0x30, 0x26, 0x31, 0x26, 0x32, 0x26, 0x61, 0x26, 0x63, 0x26, - 0x65, 0x26, 0x69, 0x26, 0x6f, 0x26, 0x73, 0x26, 0x74, 0x26, 0x20, - 0x26, 0x25, 0x26, 0x2d, 0x26, 0x2e, 0x26, 0x2f, 0x26, 0x33, 0x26, - 0x34, 0x26, 0x35, 0x26, 0x36, 0x26, 0x37, 0x26, 0x38, 0x26, 0x39}; -const uint16_t HuffDecoderCommon::table1_496_inner_[22] = { - 0x001d, 0x009d, 0x011d, 0x019d, 0x021d, 0x029d, 0x031d, 0x039d, - 0x041d, 0x049d, 0x051e, 0x059e, 0x061e, 0x069e, 0x071e, 0x079e, - 0x081e, 0x089e, 0x091e, 0x099e, 0x0a1e, 0x0a9e}; -const uint8_t HuffDecoderCommon::table1_496_outer_[64] = { - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, - 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21}; -const uint8_t HuffDecoderCommon::table1_497_emit_[92] = { - 0x26, 0x3d, 0x26, 0x41, 0x26, 0x5f, 0x26, 0x62, 0x26, 0x64, 0x26, 0x66, - 0x26, 0x67, 0x26, 0x68, 0x26, 0x6c, 0x26, 0x6d, 0x26, 0x6e, 0x26, 0x70, - 0x26, 0x72, 0x26, 0x75, 0x26, 0x3a, 0x26, 0x42, 0x26, 0x43, 0x26, 0x44, - 0x26, 0x45, 0x26, 0x46, 0x26, 0x47, 0x26, 0x48, 0x26, 0x49, 0x26, 0x4a, - 0x26, 0x4b, 0x26, 0x4c, 0x26, 0x4d, 0x26, 0x4e, 0x26, 0x4f, 0x26, 0x50, - 0x26, 0x51, 0x26, 0x52, 0x26, 0x53, 0x26, 0x54, 0x26, 0x55, 0x26, 0x56, - 0x26, 0x57, 0x26, 0x59, 0x26, 0x6a, 0x26, 0x6b, 0x26, 0x71, 0x26, 0x76, - 0x26, 0x77, 0x26, 0x78, 0x26, 0x79, 0x26, 0x7a}; -const uint16_t HuffDecoderCommon::table1_497_inner_[47] = { - 0x001e, 0x009e, 0x011e, 0x019e, 0x021e, 0x029e, 0x031e, 0x039e, - 0x041e, 0x049e, 0x051e, 0x059e, 0x061e, 0x069e, 0x071f, 0x079f, - 0x081f, 0x089f, 0x091f, 0x099f, 0x0a1f, 0x0a9f, 0x0b1f, 0x0b9f, - 0x0c1f, 0x0c9f, 0x0d1f, 0x0d9f, 0x0e1f, 0x0e9f, 0x0f1f, 0x0f9f, - 0x101f, 0x109f, 0x111f, 0x119f, 0x121f, 0x129f, 0x131f, 0x139f, - 0x141f, 0x149f, 0x151f, 0x159f, 0x161f, 0x169f, 0x0028}; -const uint8_t HuffDecoderCommon::table1_497_outer_[64] = { - 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 46, 46}; -const uint8_t HuffDecoderCommon::table1_498_emit_[44] = { - 0x2a, 0x30, 0x2a, 0x31, 0x2a, 0x32, 0x2a, 0x61, 0x2a, 0x63, 0x2a, - 0x65, 0x2a, 0x69, 0x2a, 0x6f, 0x2a, 0x73, 0x2a, 0x74, 0x2a, 0x20, - 0x2a, 0x25, 0x2a, 0x2d, 0x2a, 0x2e, 0x2a, 0x2f, 0x2a, 0x33, 0x2a, - 0x34, 0x2a, 0x35, 0x2a, 0x36, 0x2a, 0x37, 0x2a, 0x38, 0x2a, 0x39}; -const uint8_t HuffDecoderCommon::table1_499_emit_[92] = { - 0x2a, 0x3d, 0x2a, 0x41, 0x2a, 0x5f, 0x2a, 0x62, 0x2a, 0x64, 0x2a, 0x66, - 0x2a, 0x67, 0x2a, 0x68, 0x2a, 0x6c, 0x2a, 0x6d, 0x2a, 0x6e, 0x2a, 0x70, - 0x2a, 0x72, 0x2a, 0x75, 0x2a, 0x3a, 0x2a, 0x42, 0x2a, 0x43, 0x2a, 0x44, - 0x2a, 0x45, 0x2a, 0x46, 0x2a, 0x47, 0x2a, 0x48, 0x2a, 0x49, 0x2a, 0x4a, - 0x2a, 0x4b, 0x2a, 0x4c, 0x2a, 0x4d, 0x2a, 0x4e, 0x2a, 0x4f, 0x2a, 0x50, - 0x2a, 0x51, 0x2a, 0x52, 0x2a, 0x53, 0x2a, 0x54, 0x2a, 0x55, 0x2a, 0x56, - 0x2a, 0x57, 0x2a, 0x59, 0x2a, 0x6a, 0x2a, 0x6b, 0x2a, 0x71, 0x2a, 0x76, - 0x2a, 0x77, 0x2a, 0x78, 0x2a, 0x79, 0x2a, 0x7a}; -const uint8_t HuffDecoderCommon::table1_500_emit_[44] = { - 0x2c, 0x30, 0x2c, 0x31, 0x2c, 0x32, 0x2c, 0x61, 0x2c, 0x63, 0x2c, - 0x65, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x73, 0x2c, 0x74, 0x2c, 0x20, - 0x2c, 0x25, 0x2c, 0x2d, 0x2c, 0x2e, 0x2c, 0x2f, 0x2c, 0x33, 0x2c, - 0x34, 0x2c, 0x35, 0x2c, 0x36, 0x2c, 0x37, 0x2c, 0x38, 0x2c, 0x39}; -const uint8_t HuffDecoderCommon::table1_501_emit_[92] = { - 0x2c, 0x3d, 0x2c, 0x41, 0x2c, 0x5f, 0x2c, 0x62, 0x2c, 0x64, 0x2c, 0x66, - 0x2c, 0x67, 0x2c, 0x68, 0x2c, 0x6c, 0x2c, 0x6d, 0x2c, 0x6e, 0x2c, 0x70, - 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x3a, 0x2c, 0x42, 0x2c, 0x43, 0x2c, 0x44, - 0x2c, 0x45, 0x2c, 0x46, 0x2c, 0x47, 0x2c, 0x48, 0x2c, 0x49, 0x2c, 0x4a, - 0x2c, 0x4b, 0x2c, 0x4c, 0x2c, 0x4d, 0x2c, 0x4e, 0x2c, 0x4f, 0x2c, 0x50, - 0x2c, 0x51, 0x2c, 0x52, 0x2c, 0x53, 0x2c, 0x54, 0x2c, 0x55, 0x2c, 0x56, - 0x2c, 0x57, 0x2c, 0x59, 0x2c, 0x6a, 0x2c, 0x6b, 0x2c, 0x71, 0x2c, 0x76, - 0x2c, 0x77, 0x2c, 0x78, 0x2c, 0x79, 0x2c, 0x7a}; -const uint8_t HuffDecoderCommon::table1_502_emit_[44] = { - 0x3b, 0x30, 0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x61, 0x3b, 0x63, 0x3b, - 0x65, 0x3b, 0x69, 0x3b, 0x6f, 0x3b, 0x73, 0x3b, 0x74, 0x3b, 0x20, - 0x3b, 0x25, 0x3b, 0x2d, 0x3b, 0x2e, 0x3b, 0x2f, 0x3b, 0x33, 0x3b, - 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x38, 0x3b, 0x39}; -const uint8_t HuffDecoderCommon::table1_503_emit_[92] = { - 0x3b, 0x3d, 0x3b, 0x41, 0x3b, 0x5f, 0x3b, 0x62, 0x3b, 0x64, 0x3b, 0x66, - 0x3b, 0x67, 0x3b, 0x68, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x70, - 0x3b, 0x72, 0x3b, 0x75, 0x3b, 0x3a, 0x3b, 0x42, 0x3b, 0x43, 0x3b, 0x44, - 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x47, 0x3b, 0x48, 0x3b, 0x49, 0x3b, 0x4a, - 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4f, 0x3b, 0x50, - 0x3b, 0x51, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x55, 0x3b, 0x56, - 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x6a, 0x3b, 0x6b, 0x3b, 0x71, 0x3b, 0x76, - 0x3b, 0x77, 0x3b, 0x78, 0x3b, 0x79, 0x3b, 0x7a}; -const uint8_t HuffDecoderCommon::table1_504_emit_[44] = { - 0x58, 0x30, 0x58, 0x31, 0x58, 0x32, 0x58, 0x61, 0x58, 0x63, 0x58, - 0x65, 0x58, 0x69, 0x58, 0x6f, 0x58, 0x73, 0x58, 0x74, 0x58, 0x20, - 0x58, 0x25, 0x58, 0x2d, 0x58, 0x2e, 0x58, 0x2f, 0x58, 0x33, 0x58, - 0x34, 0x58, 0x35, 0x58, 0x36, 0x58, 0x37, 0x58, 0x38, 0x58, 0x39}; -const uint8_t HuffDecoderCommon::table1_505_emit_[92] = { - 0x58, 0x3d, 0x58, 0x41, 0x58, 0x5f, 0x58, 0x62, 0x58, 0x64, 0x58, 0x66, - 0x58, 0x67, 0x58, 0x68, 0x58, 0x6c, 0x58, 0x6d, 0x58, 0x6e, 0x58, 0x70, - 0x58, 0x72, 0x58, 0x75, 0x58, 0x3a, 0x58, 0x42, 0x58, 0x43, 0x58, 0x44, - 0x58, 0x45, 0x58, 0x46, 0x58, 0x47, 0x58, 0x48, 0x58, 0x49, 0x58, 0x4a, - 0x58, 0x4b, 0x58, 0x4c, 0x58, 0x4d, 0x58, 0x4e, 0x58, 0x4f, 0x58, 0x50, - 0x58, 0x51, 0x58, 0x52, 0x58, 0x53, 0x58, 0x54, 0x58, 0x55, 0x58, 0x56, - 0x58, 0x57, 0x58, 0x59, 0x58, 0x6a, 0x58, 0x6b, 0x58, 0x71, 0x58, 0x76, - 0x58, 0x77, 0x58, 0x78, 0x58, 0x79, 0x58, 0x7a}; -const uint8_t HuffDecoderCommon::table1_506_emit_[44] = { - 0x5a, 0x30, 0x5a, 0x31, 0x5a, 0x32, 0x5a, 0x61, 0x5a, 0x63, 0x5a, - 0x65, 0x5a, 0x69, 0x5a, 0x6f, 0x5a, 0x73, 0x5a, 0x74, 0x5a, 0x20, - 0x5a, 0x25, 0x5a, 0x2d, 0x5a, 0x2e, 0x5a, 0x2f, 0x5a, 0x33, 0x5a, - 0x34, 0x5a, 0x35, 0x5a, 0x36, 0x5a, 0x37, 0x5a, 0x38, 0x5a, 0x39}; -const uint8_t HuffDecoderCommon::table1_507_emit_[92] = { - 0x5a, 0x3d, 0x5a, 0x41, 0x5a, 0x5f, 0x5a, 0x62, 0x5a, 0x64, 0x5a, 0x66, - 0x5a, 0x67, 0x5a, 0x68, 0x5a, 0x6c, 0x5a, 0x6d, 0x5a, 0x6e, 0x5a, 0x70, - 0x5a, 0x72, 0x5a, 0x75, 0x5a, 0x3a, 0x5a, 0x42, 0x5a, 0x43, 0x5a, 0x44, - 0x5a, 0x45, 0x5a, 0x46, 0x5a, 0x47, 0x5a, 0x48, 0x5a, 0x49, 0x5a, 0x4a, - 0x5a, 0x4b, 0x5a, 0x4c, 0x5a, 0x4d, 0x5a, 0x4e, 0x5a, 0x4f, 0x5a, 0x50, - 0x5a, 0x51, 0x5a, 0x52, 0x5a, 0x53, 0x5a, 0x54, 0x5a, 0x55, 0x5a, 0x56, - 0x5a, 0x57, 0x5a, 0x59, 0x5a, 0x6a, 0x5a, 0x6b, 0x5a, 0x71, 0x5a, 0x76, - 0x5a, 0x77, 0x5a, 0x78, 0x5a, 0x79, 0x5a, 0x7a}; -const uint8_t HuffDecoderCommon::table1_508_emit_[40] = { - 0x21, 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x61, 0x21, 0x63, - 0x21, 0x65, 0x21, 0x69, 0x21, 0x6f, 0x21, 0x73, 0x21, 0x74, - 0x22, 0x30, 0x22, 0x31, 0x22, 0x32, 0x22, 0x61, 0x22, 0x63, - 0x22, 0x65, 0x22, 0x69, 0x22, 0x6f, 0x22, 0x73, 0x22, 0x74}; -const uint16_t HuffDecoderCommon::table1_508_inner_[22] = { - 0x001f, 0x009f, 0x011f, 0x019f, 0x021f, 0x029f, 0x031f, 0x039f, - 0x041f, 0x049f, 0x002a, 0x051f, 0x059f, 0x061f, 0x069f, 0x071f, - 0x079f, 0x081f, 0x089f, 0x091f, 0x099f, 0x052a}; -const uint8_t HuffDecoderCommon::table1_509_emit_[40] = { - 0x28, 0x30, 0x28, 0x31, 0x28, 0x32, 0x28, 0x61, 0x28, 0x63, - 0x28, 0x65, 0x28, 0x69, 0x28, 0x6f, 0x28, 0x73, 0x28, 0x74, - 0x29, 0x30, 0x29, 0x31, 0x29, 0x32, 0x29, 0x61, 0x29, 0x63, - 0x29, 0x65, 0x29, 0x69, 0x29, 0x6f, 0x29, 0x73, 0x29, 0x74}; -const uint8_t HuffDecoderCommon::table1_510_emit_[22] = { - 0x3f, 0x30, 0x3f, 0x31, 0x3f, 0x32, 0x3f, 0x61, 0x3f, 0x63, 0x3f, - 0x65, 0x3f, 0x69, 0x3f, 0x6f, 0x3f, 0x73, 0x3f, 0x74, 0x27, 0x2b}; -const uint16_t HuffDecoderCommon::table1_510_inner_[13] = { - 0x001f, 0x009f, 0x011f, 0x019f, 0x021f, 0x029f, 0x031f, - 0x039f, 0x041f, 0x049f, 0x002a, 0x052b, 0x056b}; -const uint8_t HuffDecoderCommon::table1_510_outer_[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}; -const uint8_t HuffDecoderCommon::table1_511_emit_[14] = { - 0x7c, 0x23, 0x3e, 0x00, 0x24, 0x40, 0x5b, - 0x5d, 0x7e, 0x5e, 0x7d, 0x3c, 0x60, 0x7b}; -const uint16_t HuffDecoderCommon::table1_511_inner_[15] = { - 0x002b, 0x006c, 0x00ac, 0x00ed, 0x012d, 0x016d, 0x01ad, 0x01ed, - 0x022d, 0x026e, 0x02ae, 0x02ef, 0x032f, 0x036f, 0x003f}; -const uint8_t HuffDecoderCommon::table1_511_outer_[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, 11, 12, 13, 14}; -const uint8_t* const HuffDecoderCommon::table1_emit_[512] = { +const uint16_t HuffDecoderCommon::table1_255_inner_[16] = { + 0x001a, 0x005b, 0x009b, 0x00db, 0x011c, 0x015c, 0x019d, 0x01dd, + 0x021d, 0x025d, 0x029d, 0x02dd, 0x031e, 0x035e, 0x002e, 0x003e}; +const uint8_t HuffDecoderCommon::table1_255_outer_[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, 15}; +const uint8_t* const HuffDecoderCommon::table1_emit_[256] = { table1_0_emit_, table1_1_emit_, table1_2_emit_, table1_3_emit_, table1_4_emit_, table1_5_emit_, table1_6_emit_, table1_7_emit_, table1_8_emit_, table1_9_emit_, table1_10_emit_, table1_11_emit_, @@ -6189,458 +3802,570 @@ const uint8_t* const HuffDecoderCommon::table1_emit_[512] = { table1_244_emit_, table1_245_emit_, table1_246_emit_, table1_247_emit_, table1_248_emit_, table1_249_emit_, table1_250_emit_, table1_251_emit_, table1_252_emit_, table1_253_emit_, table1_254_emit_, table1_255_emit_, - table1_256_emit_, table1_257_emit_, table1_258_emit_, table1_259_emit_, - table1_260_emit_, table1_261_emit_, table1_262_emit_, table1_263_emit_, - table1_264_emit_, table1_265_emit_, table1_266_emit_, table1_267_emit_, - table1_268_emit_, table1_269_emit_, table1_270_emit_, table1_271_emit_, - table1_272_emit_, table1_273_emit_, table1_274_emit_, table1_275_emit_, - table1_276_emit_, table1_277_emit_, table1_278_emit_, table1_279_emit_, - table1_280_emit_, table1_281_emit_, table1_282_emit_, table1_283_emit_, - table1_284_emit_, table1_285_emit_, table1_286_emit_, table1_287_emit_, - table1_288_emit_, table1_289_emit_, table1_290_emit_, table1_291_emit_, - table1_292_emit_, table1_293_emit_, table1_294_emit_, table1_295_emit_, - table1_296_emit_, table1_297_emit_, table1_298_emit_, table1_299_emit_, - table1_300_emit_, table1_301_emit_, table1_302_emit_, table1_303_emit_, - table1_304_emit_, table1_305_emit_, table1_306_emit_, table1_307_emit_, - table1_308_emit_, table1_309_emit_, table1_310_emit_, table1_311_emit_, - table1_312_emit_, table1_313_emit_, table1_314_emit_, table1_315_emit_, - table1_316_emit_, table1_317_emit_, table1_318_emit_, table1_319_emit_, - table1_320_emit_, table1_321_emit_, table1_322_emit_, table1_323_emit_, - table1_324_emit_, table1_325_emit_, table1_326_emit_, table1_327_emit_, - table1_328_emit_, table1_329_emit_, table1_330_emit_, table1_331_emit_, - table1_332_emit_, table1_333_emit_, table1_334_emit_, table1_335_emit_, - table1_336_emit_, table1_337_emit_, table1_338_emit_, table1_339_emit_, - table1_340_emit_, table1_341_emit_, table1_342_emit_, table1_343_emit_, - table1_344_emit_, table1_345_emit_, table1_346_emit_, table1_347_emit_, - table1_348_emit_, table1_349_emit_, table1_350_emit_, table1_351_emit_, - table1_352_emit_, table1_353_emit_, table1_354_emit_, table1_355_emit_, - table1_356_emit_, table1_357_emit_, table1_358_emit_, table1_359_emit_, - table1_360_emit_, table1_361_emit_, table1_362_emit_, table1_363_emit_, - table1_364_emit_, table1_365_emit_, table1_366_emit_, table1_367_emit_, - table1_368_emit_, table1_369_emit_, table1_370_emit_, table1_371_emit_, - table1_372_emit_, table1_373_emit_, table1_374_emit_, table1_375_emit_, - table1_376_emit_, table1_377_emit_, table1_378_emit_, table1_379_emit_, - table1_380_emit_, table1_381_emit_, table1_382_emit_, table1_383_emit_, - table1_384_emit_, table1_385_emit_, table1_386_emit_, table1_387_emit_, - table1_388_emit_, table1_389_emit_, table1_390_emit_, table1_391_emit_, - table1_392_emit_, table1_393_emit_, table1_394_emit_, table1_395_emit_, - table1_396_emit_, table1_397_emit_, table1_398_emit_, table1_399_emit_, - table1_400_emit_, table1_401_emit_, table1_402_emit_, table1_403_emit_, - table1_404_emit_, table1_405_emit_, table1_406_emit_, table1_407_emit_, - table1_408_emit_, table1_409_emit_, table1_410_emit_, table1_411_emit_, - table1_412_emit_, table1_413_emit_, table1_414_emit_, table1_415_emit_, - table1_416_emit_, table1_417_emit_, table1_418_emit_, table1_419_emit_, - table1_420_emit_, table1_421_emit_, table1_422_emit_, table1_423_emit_, - table1_424_emit_, table1_425_emit_, table1_426_emit_, table1_427_emit_, - table1_428_emit_, table1_429_emit_, table1_430_emit_, table1_431_emit_, - table1_432_emit_, table1_433_emit_, table1_434_emit_, table1_435_emit_, - table1_436_emit_, table1_437_emit_, table1_438_emit_, table1_439_emit_, - table1_440_emit_, table1_441_emit_, table1_442_emit_, table1_443_emit_, - table1_444_emit_, table1_445_emit_, table1_446_emit_, table1_447_emit_, - table1_448_emit_, table1_449_emit_, table1_450_emit_, table1_451_emit_, - table1_452_emit_, table1_453_emit_, table1_454_emit_, table1_455_emit_, - table1_456_emit_, table1_457_emit_, table1_458_emit_, table1_459_emit_, - table1_460_emit_, table1_461_emit_, table1_462_emit_, table1_463_emit_, - table1_464_emit_, table1_465_emit_, table1_466_emit_, table1_467_emit_, - table1_468_emit_, table1_469_emit_, table1_470_emit_, table1_471_emit_, - table1_472_emit_, table1_473_emit_, table1_474_emit_, table1_475_emit_, - table1_476_emit_, table1_477_emit_, table1_478_emit_, table1_479_emit_, - table1_480_emit_, table1_481_emit_, table1_482_emit_, table1_483_emit_, - table1_484_emit_, table1_485_emit_, table1_486_emit_, table1_487_emit_, - table1_488_emit_, table1_489_emit_, table1_490_emit_, table1_491_emit_, - table1_492_emit_, table1_493_emit_, table1_494_emit_, table1_495_emit_, - table1_496_emit_, table1_497_emit_, table1_498_emit_, table1_499_emit_, - table1_500_emit_, table1_501_emit_, table1_502_emit_, table1_503_emit_, - table1_504_emit_, table1_505_emit_, table1_506_emit_, table1_507_emit_, - table1_508_emit_, table1_509_emit_, table1_510_emit_, table1_511_emit_, }; -const uint16_t* const HuffDecoderCommon::table1_inner_[512] = { - table1_0_inner_, table1_1_inner_, table1_1_inner_, table1_1_inner_, - table1_1_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_16_inner_, table1_17_inner_, table1_17_inner_, table1_17_inner_, - table1_17_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_32_inner_, table1_33_inner_, table1_32_inner_, table1_32_inner_, - table1_32_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_48_inner_, table1_49_inner_, table1_48_inner_, table1_48_inner_, - table1_48_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_64_inner_, table1_64_inner_, table1_66_inner_, table1_64_inner_, - table1_64_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_80_inner_, table1_80_inner_, table1_82_inner_, table1_80_inner_, - table1_80_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_96_inner_, table1_96_inner_, table1_96_inner_, table1_99_inner_, - table1_96_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_112_inner_, table1_112_inner_, table1_112_inner_, table1_115_inner_, - table1_112_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_128_inner_, table1_128_inner_, table1_128_inner_, table1_128_inner_, - table1_132_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_144_inner_, table1_144_inner_, table1_144_inner_, table1_144_inner_, - table1_144_inner_, table1_5_inner_, table1_5_inner_, table1_5_inner_, - table1_5_inner_, table1_5_inner_, table1_5_inner_, table1_11_inner_, - table1_12_inner_, table1_12_inner_, table1_12_inner_, table1_15_inner_, - table1_5_inner_, table1_5_inner_, table1_162_inner_, table1_12_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_170_inner_, table1_12_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_178_inner_, table1_12_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_195_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_203_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_211_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_219_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_227_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_235_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_243_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_195_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_203_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_211_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_219_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_227_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_235_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_243_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_165_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_325_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_333_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_341_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_349_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_357_inner_, table1_166_inner_, table1_167_inner_, - table1_5_inner_, table1_5_inner_, table1_11_inner_, table1_12_inner_, - table1_12_inner_, table1_365_inner_, table1_166_inner_, table1_167_inner_, - table1_12_inner_, table1_369_inner_, table1_370_inner_, table1_371_inner_, - table1_12_inner_, table1_369_inner_, table1_374_inner_, table1_371_inner_, - table1_12_inner_, table1_369_inner_, table1_378_inner_, table1_371_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_371_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_387_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_391_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_395_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_399_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_403_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_407_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_411_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_415_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_419_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_423_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_427_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_431_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_435_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_439_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_443_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_447_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_451_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_455_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_459_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_463_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_467_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_471_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_475_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_479_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_483_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_487_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_491_inner_, - table1_12_inner_, table1_369_inner_, table1_382_inner_, table1_495_inner_, - table1_496_inner_, table1_497_inner_, table1_496_inner_, table1_497_inner_, - table1_496_inner_, table1_497_inner_, table1_496_inner_, table1_497_inner_, - table1_496_inner_, table1_497_inner_, table1_496_inner_, table1_497_inner_, - table1_508_inner_, table1_508_inner_, table1_510_inner_, table1_511_inner_, +const uint16_t* const HuffDecoderCommon::table1_inner_[256] = { + table1_0_inner_, table1_1_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_8_inner_, table1_1_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_16_inner_, table1_1_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_1_inner_, table1_1_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_1_inner_, table1_0_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_1_inner_, table1_8_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_1_inner_, table1_16_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_1_inner_, table1_1_inner_, table1_2_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_1_inner_, table1_1_inner_, table1_66_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_1_inner_, table1_1_inner_, table1_74_inner_, table1_3_inner_, + table1_3_inner_, table1_5_inner_, table1_6_inner_, table1_7_inner_, + table1_3_inner_, table1_81_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_85_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_89_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_93_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_97_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_101_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_105_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_109_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_113_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_117_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_121_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_82_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_130_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_134_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_138_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_142_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_146_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_150_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_154_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_158_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_162_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_166_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_170_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_174_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_178_inner_, table1_83_inner_, + table1_3_inner_, table1_125_inner_, table1_182_inner_, table1_83_inner_, + table1_184_inner_, table1_185_inner_, table1_184_inner_, table1_187_inner_, + table1_184_inner_, table1_189_inner_, table1_184_inner_, table1_191_inner_, + table1_184_inner_, table1_193_inner_, table1_184_inner_, table1_195_inner_, + table1_184_inner_, table1_197_inner_, table1_184_inner_, table1_199_inner_, + table1_184_inner_, table1_201_inner_, table1_184_inner_, table1_203_inner_, + table1_184_inner_, table1_205_inner_, table1_184_inner_, table1_207_inner_, + table1_184_inner_, table1_209_inner_, table1_184_inner_, table1_211_inner_, + table1_184_inner_, table1_213_inner_, table1_184_inner_, table1_215_inner_, + table1_184_inner_, table1_217_inner_, table1_184_inner_, table1_219_inner_, + table1_184_inner_, table1_221_inner_, table1_184_inner_, table1_223_inner_, + table1_184_inner_, table1_225_inner_, table1_184_inner_, table1_227_inner_, + table1_184_inner_, table1_229_inner_, table1_184_inner_, table1_231_inner_, + table1_184_inner_, table1_233_inner_, table1_184_inner_, table1_235_inner_, + table1_184_inner_, table1_237_inner_, table1_184_inner_, table1_239_inner_, + table1_184_inner_, table1_241_inner_, table1_184_inner_, table1_243_inner_, + table1_184_inner_, table1_245_inner_, table1_184_inner_, table1_247_inner_, + table1_248_inner_, table1_248_inner_, table1_248_inner_, table1_248_inner_, + table1_248_inner_, table1_248_inner_, table1_254_inner_, table1_255_inner_, }; -const uint8_t* const HuffDecoderCommon::table1_outer_[512] = { - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_0_outer_, table1_0_outer_, table1_0_outer_, table1_0_outer_, - table1_0_outer_, table1_5_outer_, table1_5_outer_, table1_5_outer_, - table1_5_outer_, table1_5_outer_, table1_5_outer_, table1_11_outer_, - table1_12_outer_, table1_12_outer_, table1_12_outer_, table1_15_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_5_outer_, table1_5_outer_, table1_11_outer_, table1_12_outer_, - table1_12_outer_, table1_165_outer_, table1_166_outer_, table1_167_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_12_outer_, table1_369_outer_, table1_370_outer_, table1_371_outer_, - table1_496_outer_, table1_497_outer_, table1_496_outer_, table1_497_outer_, - table1_496_outer_, table1_497_outer_, table1_496_outer_, table1_497_outer_, - table1_496_outer_, table1_497_outer_, table1_496_outer_, table1_497_outer_, - table1_0_outer_, table1_0_outer_, table1_510_outer_, table1_511_outer_, +const uint8_t* const HuffDecoderCommon::table1_outer_[256] = { + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_0_outer_, table1_0_outer_, table1_2_outer_, table1_3_outer_, + table1_3_outer_, table1_5_outer_, table1_6_outer_, table1_7_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_3_outer_, table1_81_outer_, table1_82_outer_, table1_83_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_184_outer_, table1_185_outer_, table1_184_outer_, table1_185_outer_, + table1_248_outer_, table1_248_outer_, table1_248_outer_, table1_248_outer_, + table1_248_outer_, table1_248_outer_, table1_0_outer_, table1_255_outer_, }; -const uint8_t HuffDecoderCommon::table13_0_inner_[5] = {0x00, 0x04, 0x08, 0x01, - 0x02}; -const uint8_t HuffDecoderCommon::table14_0_emit_[11] = { - 0x5c, 0xc3, 0xd0, 0x80, 0x82, 0x83, 0xa2, 0xb8, 0xc2, 0xe0, 0xe2}; -const uint8_t HuffDecoderCommon::table14_0_ops_[32] = { - 0x00, 0x01, 0x00, 0x05, 0x00, 0x09, 0x0d, 0x11, 0x15, 0x19, 0x1d, - 0x21, 0x25, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +const uint8_t HuffDecoderCommon::table15_0_outer_[8] = {0, 0, 0, 1, 0, 0, 0, 2}; +const uint8_t HuffDecoderCommon::table16_0_outer_[16] = { + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2}; +const uint16_t HuffDecoderCommon::table12_0_inner_[17] = { + 0x0001, 0x0085, 0x0105, 0x0185, 0x000d, 0x0015, 0x001d, 0x0025, 0x002d, + 0x0035, 0x003d, 0x0045, 0x004d, 0x0055, 0x005d, 0x0065, 0x006d}; +const uint8_t HuffDecoderCommon::table24_0_emit_[8] = {0x9a, 0x9c, 0xa0, 0xa3, + 0xa4, 0xa9, 0xaa, 0xad}; +const uint8_t HuffDecoderCommon::table24_0_inner_[8] = {0x03, 0x07, 0x0b, 0x0f, + 0x13, 0x17, 0x1b, 0x1f}; +const uint8_t HuffDecoderCommon::table25_0_emit_[8] = {0xb2, 0xb5, 0xb9, 0xba, + 0xbb, 0xbd, 0xbe, 0xc4}; +const uint8_t HuffDecoderCommon::table26_0_emit_[16] = { + 0x93, 0x95, 0x96, 0x97, 0x98, 0x9b, 0x9d, 0x9e, + 0xa5, 0xa6, 0xa8, 0xae, 0xaf, 0xb4, 0xb6, 0xb7}; +const uint8_t HuffDecoderCommon::table26_0_inner_[16] = { + 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c, + 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c}; +const uint8_t HuffDecoderCommon::table27_0_emit_[7] = {0xe6, 0x81, 0x84, 0x85, + 0x86, 0x88, 0x92}; +const uint8_t HuffDecoderCommon::table27_0_inner_[7] = {0x02, 0x07, 0x0b, 0x0f, + 0x13, 0x17, 0x1b}; +const uint8_t HuffDecoderCommon::table30_0_inner_[5] = {0x00, 0x02, 0x04, 0x06, + 0x01}; +const uint8_t HuffDecoderCommon::table29_0_emit_[12] = { + 0xc6, 0xe4, 0xe8, 0xe9, 0x01, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8f}; +const uint8_t HuffDecoderCommon::table29_0_inner_[12] = { + 0x03, 0x0b, 0x13, 0x1b, 0x24, 0x2c, 0x34, 0x3c, 0x44, 0x4c, 0x54, 0x5c}; +const uint8_t HuffDecoderCommon::table32_0_emit_[5] = {0xbc, 0xbf, 0xc5, 0xe7, + 0xef}; +const uint8_t HuffDecoderCommon::table32_0_inner_[7] = {0x00, 0x04, 0x08, 0x0c, + 0x10, 0x01, 0x02}; +const uint8_t HuffDecoderCommon::table33_0_emit_[17] = { + 0xbc, 0xbf, 0xc5, 0xe7, 0xef, 0x09, 0x8e, 0x90, 0x91, + 0x94, 0x9f, 0xab, 0xce, 0xd7, 0xe1, 0xec, 0xed}; +const uint8_t HuffDecoderCommon::table33_0_ops_[32] = { + 0x00, 0x01, 0x00, 0x05, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x11, 0x15, + 0x19, 0x1d, 0x21, 0x25, 0x29, 0x2d, 0x31, 0x35, 0x39, 0x3d, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; -const uint8_t HuffDecoderCommon::table15_0_emit_[24] = { - 0x5c, 0xc3, 0xd0, 0x80, 0x82, 0x83, 0xa2, 0xb8, 0xc2, 0xe0, 0xe2, 0x99, - 0xa1, 0xa7, 0xac, 0xb0, 0xb1, 0xb3, 0xd1, 0xd8, 0xd9, 0xe3, 0xe5, 0xe6}; -const uint8_t HuffDecoderCommon::table15_0_ops_[64] = { +const uint8_t HuffDecoderCommon::table34_0_emit_[21] = { + 0xbc, 0xbf, 0xc5, 0xe7, 0xef, 0x09, 0x8e, 0x90, 0x91, 0x94, 0x9f, + 0xab, 0xce, 0xd7, 0xe1, 0xec, 0xed, 0xc7, 0xcf, 0xea, 0xeb}; +const uint8_t HuffDecoderCommon::table34_0_ops_[64] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x0d, 0x00, 0x11, 0x00, 0x15, 0x00, 0x19, 0x00, 0x1d, - 0x00, 0x21, 0x00, 0x25, 0x00, 0x29, 0x2d, 0x31, 0x35, 0x39, 0x3d, - 0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x15, + 0x00, 0x19, 0x00, 0x1d, 0x00, 0x21, 0x00, 0x25, 0x00, 0x29, 0x00, + 0x2d, 0x00, 0x31, 0x00, 0x35, 0x00, 0x39, 0x00, 0x3d, 0x00, 0x41, + 0x45, 0x49, 0x4d, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; -const uint8_t HuffDecoderCommon::table12_0_emit_[50] = { - 0x5c, 0xc3, 0xd0, 0x80, 0x82, 0x83, 0xa2, 0xb8, 0xc2, 0xe0, - 0xe2, 0x99, 0xa1, 0xa7, 0xac, 0xb0, 0xb1, 0xb3, 0xd1, 0xd8, - 0xd9, 0xe3, 0xe5, 0xe6, 0x81, 0x84, 0x85, 0x86, 0x88, 0x92, - 0x9a, 0x9c, 0xa0, 0xa3, 0xa4, 0xa9, 0xaa, 0xad, 0xb2, 0xb5, - 0xb9, 0xba, 0xbb, 0xbd, 0xbe, 0xc4, 0xc6, 0xe4, 0xe8, 0xe9}; -const uint16_t HuffDecoderCommon::table12_0_inner_[70] = { - 0x0004, 0x0104, 0x0204, 0x0305, 0x0405, 0x0505, 0x0605, 0x0705, 0x0805, - 0x0905, 0x0a05, 0x0b06, 0x0c06, 0x0d06, 0x0e06, 0x0f06, 0x1006, 0x1106, - 0x1206, 0x1306, 0x1406, 0x1506, 0x1606, 0x1706, 0x1807, 0x1907, 0x1a07, - 0x1b07, 0x1c07, 0x1d07, 0x1e07, 0x1f07, 0x2007, 0x2107, 0x2207, 0x2307, - 0x2407, 0x2507, 0x2607, 0x2707, 0x2807, 0x2907, 0x2a07, 0x2b07, 0x2c07, - 0x2d07, 0x2e07, 0x2f07, 0x3007, 0x3107, 0x000f, 0x0017, 0x001f, 0x0027, - 0x002f, 0x0037, 0x003f, 0x0047, 0x004f, 0x0057, 0x005f, 0x0067, 0x006f, - 0x0077, 0x007f, 0x0087, 0x008f, 0x0097, 0x009f, 0x00a7}; -const uint8_t HuffDecoderCommon::table12_0_outer_[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, - 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, - 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, - 21, 21, 22, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69}; -const uint8_t HuffDecoderCommon::table33_0_emit_[15] = { - 0xc0, 0xc1, 0xc8, 0xc9, 0xca, 0xcd, 0xd2, 0xd5, - 0xda, 0xdb, 0xee, 0xf0, 0xf2, 0xf3, 0xff}; -const uint8_t HuffDecoderCommon::table33_0_inner_[16] = { - 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, - 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x01}; -const uint8_t HuffDecoderCommon::table32_0_emit_[17] = { +const uint8_t HuffDecoderCommon::table35_0_emit_[36] = { + 0xbc, 0xbf, 0xc5, 0xe7, 0xef, 0x09, 0x8e, 0x90, 0x91, 0x94, 0x9f, 0xab, + 0xce, 0xd7, 0xe1, 0xec, 0xed, 0xc7, 0xcf, 0xea, 0xeb, 0xc0, 0xc1, 0xc8, + 0xc9, 0xca, 0xcd, 0xd2, 0xd5, 0xda, 0xdb, 0xee, 0xf0, 0xf2, 0xf3, 0xff}; +const uint8_t HuffDecoderCommon::table35_0_ops_[128] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x25, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x45, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x51, + 0x55, 0x59, 0x5d, 0x61, 0x65, 0x69, 0x6d, 0x71, 0x75, 0x79, 0x7d, 0x81, + 0x85, 0x89, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; +const uint8_t HuffDecoderCommon::table36_0_emit_[55] = { + 0xbc, 0xbf, 0xc5, 0xe7, 0xef, 0x09, 0x8e, 0x90, 0x91, 0x94, 0x9f, + 0xab, 0xce, 0xd7, 0xe1, 0xec, 0xed, 0xc7, 0xcf, 0xea, 0xeb, 0xc0, + 0xc1, 0xc8, 0xc9, 0xca, 0xcd, 0xd2, 0xd5, 0xda, 0xdb, 0xee, 0xf0, + 0xf2, 0xf3, 0xff, 0xcb, 0xcc, 0xd3, 0xd4, 0xd6, 0xdd, 0xde, 0xdf, + 0xf1, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe}; +const uint8_t HuffDecoderCommon::table36_0_ops_[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x45, + 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x51, + 0x00, 0x55, 0x00, 0x59, 0x00, 0x5d, 0x00, 0x61, 0x00, 0x65, 0x00, 0x69, + 0x00, 0x6d, 0x00, 0x71, 0x00, 0x75, 0x00, 0x79, 0x00, 0x7d, 0x00, 0x81, + 0x00, 0x85, 0x00, 0x89, 0x00, 0x8d, 0x91, 0x95, 0x99, 0x9d, 0xa1, 0xa5, + 0xa9, 0xad, 0xb1, 0xb5, 0xb9, 0xbd, 0xc1, 0xc5, 0xc9, 0xcd, 0xd1, 0xd5, + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02}; +const uint8_t HuffDecoderCommon::table37_0_emit_[40] = { + 0xbc, 0x30, 0xbc, 0x31, 0xbc, 0x32, 0xbc, 0x61, 0xbc, 0x63, + 0xbc, 0x65, 0xbc, 0x69, 0xbc, 0x6f, 0xbc, 0x73, 0xbc, 0x74, + 0xbf, 0x30, 0xbf, 0x31, 0xbf, 0x32, 0xbf, 0x61, 0xbf, 0x63, + 0xbf, 0x65, 0xbf, 0x69, 0xbf, 0x6f, 0xbf, 0x73, 0xbf, 0x74}; +const uint8_t HuffDecoderCommon::table37_0_ops_[64] = { + 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x50, + 0x58, 0x60, 0x68, 0x70, 0x78, 0x80, 0x88, 0x90, 0x98, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x52}; +const uint8_t HuffDecoderCommon::table37_1_emit_[40] = { + 0xc5, 0x30, 0xc5, 0x31, 0xc5, 0x32, 0xc5, 0x61, 0xc5, 0x63, + 0xc5, 0x65, 0xc5, 0x69, 0xc5, 0x6f, 0xc5, 0x73, 0xc5, 0x74, + 0xe7, 0x30, 0xe7, 0x31, 0xe7, 0x32, 0xe7, 0x61, 0xe7, 0x63, + 0xe7, 0x65, 0xe7, 0x69, 0xe7, 0x6f, 0xe7, 0x73, 0xe7, 0x74}; +const uint8_t HuffDecoderCommon::table37_2_emit_[22] = { + 0xef, 0x30, 0xef, 0x31, 0xef, 0x32, 0xef, 0x61, 0xef, 0x63, 0xef, + 0x65, 0xef, 0x69, 0xef, 0x6f, 0xef, 0x73, 0xef, 0x74, 0x09, 0x8e}; +const uint8_t HuffDecoderCommon::table37_2_ops_[64] = { + 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x52, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x56}; +const uint8_t HuffDecoderCommon::table37_3_emit_[4] = {0x90, 0x91, 0x94, 0x9f}; +const uint8_t HuffDecoderCommon::table37_4_emit_[4] = {0xab, 0xce, 0xd7, 0xe1}; +const uint8_t HuffDecoderCommon::table37_5_emit_[6] = {0xec, 0xed, 0xc7, + 0xcf, 0xea, 0xeb}; +const uint8_t HuffDecoderCommon::table37_6_emit_[17] = { 0xc0, 0xc1, 0xc8, 0xc9, 0xca, 0xcd, 0xd2, 0xd5, 0xda, 0xdb, 0xee, 0xf0, 0xf2, 0xf3, 0xff, 0xcb, 0xcc}; -const uint8_t HuffDecoderCommon::table32_0_ops_[32] = { - 0x04, 0x04, 0x0c, 0x0c, 0x14, 0x14, 0x1c, 0x1c, 0x24, 0x24, 0x2c, - 0x2c, 0x34, 0x34, 0x3c, 0x3c, 0x44, 0x44, 0x4c, 0x4c, 0x54, 0x54, - 0x5c, 0x5c, 0x64, 0x64, 0x6c, 0x6c, 0x74, 0x74, 0x7d, 0x85}; -const uint8_t HuffDecoderCommon::table36_0_emit_[6] = {0xec, 0xed, 0xc7, - 0xcf, 0xea, 0xeb}; -const uint8_t HuffDecoderCommon::table36_0_inner_[6] = {0x02, 0x06, 0x0b, - 0x0f, 0x13, 0x17}; -const uint8_t HuffDecoderCommon::table39_0_emit_[17] = { - 0xd3, 0xd4, 0xd6, 0xdd, 0xde, 0xdf, 0xf1, 0xf4, 0xf5, - 0xf6, 0xf7, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe}; -const uint8_t HuffDecoderCommon::table39_0_ops_[32] = { - 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, - 0x2c, 0x30, 0x34, 0x38, 0x3c, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02}; -const uint8_t HuffDecoderCommon::table40_0_emit_[46] = { +const uint8_t HuffDecoderCommon::table37_6_ops_[64] = { + 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x06, 0x01, 0x01, 0x01, + 0x0a, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, + 0x01, 0x16, 0x01, 0x01, 0x01, 0x1a, 0x01, 0x01, 0x01, 0x1e, 0x01, + 0x01, 0x01, 0x22, 0x01, 0x01, 0x01, 0x26, 0x01, 0x01, 0x01, 0x2a, + 0x01, 0x01, 0x01, 0x2e, 0x01, 0x01, 0x01, 0x32, 0x01, 0x01, 0x01, + 0x36, 0x01, 0x01, 0x01, 0x3a, 0x01, 0x3e, 0x01, 0x42}; +const uint8_t HuffDecoderCommon::table37_7_emit_[46] = { 0xd3, 0xd4, 0xd6, 0xdd, 0xde, 0xdf, 0xf1, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x7f, 0xdc, 0xf9}; -const uint8_t HuffDecoderCommon::table40_0_ops_[64] = { - 0x00, 0x01, 0x00, 0x05, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x11, 0x00, - 0x15, 0x00, 0x19, 0x00, 0x1d, 0x00, 0x21, 0x00, 0x25, 0x00, 0x29, - 0x00, 0x2d, 0x00, 0x31, 0x00, 0x35, 0x00, 0x39, 0x00, 0x3d, 0x00, - 0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d, 0x61, 0x65, 0x69, - 0x6d, 0x71, 0x75, 0x79, 0x7d, 0x81, 0x85, 0x89, 0x8d, 0x91, 0x95, - 0x99, 0x9d, 0xa1, 0xa5, 0xa9, 0xad, 0xb1, 0xb5, 0x02}; -const uint8_t HuffDecoderCommon::table41_0_ops_[128] = { - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, - 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2d, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x45, 0x00, 0x49, - 0x00, 0x4d, 0x00, 0x51, 0x00, 0x55, 0x00, 0x59, 0x00, 0x5d, 0x00, 0x61, - 0x00, 0x65, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x71, 0x00, 0x75, 0x00, 0x79, - 0x00, 0x7d, 0x00, 0x81, 0x00, 0x85, 0x00, 0x89, 0x00, 0x8d, 0x00, 0x91, - 0x00, 0x95, 0x00, 0x99, 0x00, 0x9d, 0x00, 0xa1, 0x00, 0xa5, 0x00, 0xa9, - 0x00, 0xad, 0x00, 0xb1, 0x00, 0xb5, 0x00, 0x02}; -const uint8_t HuffDecoderCommon::table38_0_emit_[4] = {0xd3, 0xd4, 0xd6, 0xdd}; -const uint16_t HuffDecoderCommon::table38_0_ops_[32] = { +const uint8_t HuffDecoderCommon::table37_7_ops_[64] = { + 0x01, 0x02, 0x01, 0x06, 0x01, 0x0a, 0x01, 0x0e, 0x01, 0x12, 0x01, + 0x16, 0x01, 0x1a, 0x01, 0x1e, 0x01, 0x22, 0x01, 0x26, 0x01, 0x2a, + 0x01, 0x2e, 0x01, 0x32, 0x01, 0x36, 0x01, 0x3a, 0x01, 0x3e, 0x01, + 0x42, 0x46, 0x4a, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, + 0x6e, 0x72, 0x76, 0x7a, 0x7e, 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, + 0x9a, 0x9e, 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0x03}; +const uint8_t* const HuffDecoderCommon::table37_emit_[8] = { + table37_0_emit_, table37_1_emit_, table37_2_emit_, table37_3_emit_, + table37_4_emit_, table37_5_emit_, table37_6_emit_, table37_7_emit_, +}; +const uint8_t* const HuffDecoderCommon::table37_ops_[8] = { + table37_0_ops_, table37_0_ops_, table37_2_ops_, table7_5_ops_, + table7_5_ops_, table7_11_ops_, table37_6_ops_, table37_7_ops_, +}; +const uint8_t HuffDecoderCommon::table38_0_emit_[72] = { + 0xbc, 0x30, 0xbc, 0x31, 0xbc, 0x32, 0xbc, 0x61, 0xbc, 0x63, 0xbc, 0x65, + 0xbc, 0x69, 0xbc, 0x6f, 0xbc, 0x73, 0xbc, 0x74, 0xbc, 0x20, 0xbc, 0x25, + 0xbc, 0x2d, 0xbc, 0x2e, 0xbc, 0x2f, 0xbc, 0x33, 0xbc, 0x34, 0xbc, 0x35, + 0xbc, 0x36, 0xbc, 0x37, 0xbc, 0x38, 0xbc, 0x39, 0xbc, 0x3d, 0xbc, 0x41, + 0xbc, 0x5f, 0xbc, 0x62, 0xbc, 0x64, 0xbc, 0x66, 0xbc, 0x67, 0xbc, 0x68, + 0xbc, 0x6c, 0xbc, 0x6d, 0xbc, 0x6e, 0xbc, 0x70, 0xbc, 0x72, 0xbc, 0x75}; +const uint16_t HuffDecoderCommon::table38_0_ops_[64] = { + 0x0000, 0x0001, 0x0000, 0x0009, 0x0000, 0x0011, 0x0000, 0x0019, + 0x0000, 0x0021, 0x0000, 0x0029, 0x0000, 0x0031, 0x0000, 0x0039, + 0x0000, 0x0041, 0x0000, 0x0049, 0x0051, 0x0059, 0x0061, 0x0069, + 0x0071, 0x0079, 0x0081, 0x0089, 0x0091, 0x0099, 0x00a1, 0x00a9, + 0x00b1, 0x00b9, 0x00c1, 0x00c9, 0x00d1, 0x00d9, 0x00e1, 0x00e9, + 0x00f1, 0x00f9, 0x0101, 0x0109, 0x0111, 0x0119, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002}; +const uint8_t HuffDecoderCommon::table38_1_emit_[72] = { + 0xbf, 0x30, 0xbf, 0x31, 0xbf, 0x32, 0xbf, 0x61, 0xbf, 0x63, 0xbf, 0x65, + 0xbf, 0x69, 0xbf, 0x6f, 0xbf, 0x73, 0xbf, 0x74, 0xbf, 0x20, 0xbf, 0x25, + 0xbf, 0x2d, 0xbf, 0x2e, 0xbf, 0x2f, 0xbf, 0x33, 0xbf, 0x34, 0xbf, 0x35, + 0xbf, 0x36, 0xbf, 0x37, 0xbf, 0x38, 0xbf, 0x39, 0xbf, 0x3d, 0xbf, 0x41, + 0xbf, 0x5f, 0xbf, 0x62, 0xbf, 0x64, 0xbf, 0x66, 0xbf, 0x67, 0xbf, 0x68, + 0xbf, 0x6c, 0xbf, 0x6d, 0xbf, 0x6e, 0xbf, 0x70, 0xbf, 0x72, 0xbf, 0x75}; +const uint8_t HuffDecoderCommon::table38_2_emit_[72] = { + 0xc5, 0x30, 0xc5, 0x31, 0xc5, 0x32, 0xc5, 0x61, 0xc5, 0x63, 0xc5, 0x65, + 0xc5, 0x69, 0xc5, 0x6f, 0xc5, 0x73, 0xc5, 0x74, 0xc5, 0x20, 0xc5, 0x25, + 0xc5, 0x2d, 0xc5, 0x2e, 0xc5, 0x2f, 0xc5, 0x33, 0xc5, 0x34, 0xc5, 0x35, + 0xc5, 0x36, 0xc5, 0x37, 0xc5, 0x38, 0xc5, 0x39, 0xc5, 0x3d, 0xc5, 0x41, + 0xc5, 0x5f, 0xc5, 0x62, 0xc5, 0x64, 0xc5, 0x66, 0xc5, 0x67, 0xc5, 0x68, + 0xc5, 0x6c, 0xc5, 0x6d, 0xc5, 0x6e, 0xc5, 0x70, 0xc5, 0x72, 0xc5, 0x75}; +const uint8_t HuffDecoderCommon::table38_3_emit_[72] = { + 0xe7, 0x30, 0xe7, 0x31, 0xe7, 0x32, 0xe7, 0x61, 0xe7, 0x63, 0xe7, 0x65, + 0xe7, 0x69, 0xe7, 0x6f, 0xe7, 0x73, 0xe7, 0x74, 0xe7, 0x20, 0xe7, 0x25, + 0xe7, 0x2d, 0xe7, 0x2e, 0xe7, 0x2f, 0xe7, 0x33, 0xe7, 0x34, 0xe7, 0x35, + 0xe7, 0x36, 0xe7, 0x37, 0xe7, 0x38, 0xe7, 0x39, 0xe7, 0x3d, 0xe7, 0x41, + 0xe7, 0x5f, 0xe7, 0x62, 0xe7, 0x64, 0xe7, 0x66, 0xe7, 0x67, 0xe7, 0x68, + 0xe7, 0x6c, 0xe7, 0x6d, 0xe7, 0x6e, 0xe7, 0x70, 0xe7, 0x72, 0xe7, 0x75}; +const uint8_t HuffDecoderCommon::table38_4_emit_[72] = { + 0xef, 0x30, 0xef, 0x31, 0xef, 0x32, 0xef, 0x61, 0xef, 0x63, 0xef, 0x65, + 0xef, 0x69, 0xef, 0x6f, 0xef, 0x73, 0xef, 0x74, 0xef, 0x20, 0xef, 0x25, + 0xef, 0x2d, 0xef, 0x2e, 0xef, 0x2f, 0xef, 0x33, 0xef, 0x34, 0xef, 0x35, + 0xef, 0x36, 0xef, 0x37, 0xef, 0x38, 0xef, 0x39, 0xef, 0x3d, 0xef, 0x41, + 0xef, 0x5f, 0xef, 0x62, 0xef, 0x64, 0xef, 0x66, 0xef, 0x67, 0xef, 0x68, + 0xef, 0x6c, 0xef, 0x6d, 0xef, 0x6e, 0xef, 0x70, 0xef, 0x72, 0xef, 0x75}; +const uint8_t HuffDecoderCommon::table38_5_emit_[40] = { + 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x61, 0x09, 0x63, + 0x09, 0x65, 0x09, 0x69, 0x09, 0x6f, 0x09, 0x73, 0x09, 0x74, + 0x8e, 0x30, 0x8e, 0x31, 0x8e, 0x32, 0x8e, 0x61, 0x8e, 0x63, + 0x8e, 0x65, 0x8e, 0x69, 0x8e, 0x6f, 0x8e, 0x73, 0x8e, 0x74}; +const uint16_t HuffDecoderCommon::table38_5_ops_[64] = { + 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, 0x0039, + 0x0041, 0x0049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, + 0x0051, 0x0059, 0x0061, 0x0069, 0x0071, 0x0079, 0x0081, 0x0089, + 0x0091, 0x0099, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0052}; +const uint8_t HuffDecoderCommon::table38_6_emit_[40] = { + 0x90, 0x30, 0x90, 0x31, 0x90, 0x32, 0x90, 0x61, 0x90, 0x63, + 0x90, 0x65, 0x90, 0x69, 0x90, 0x6f, 0x90, 0x73, 0x90, 0x74, + 0x91, 0x30, 0x91, 0x31, 0x91, 0x32, 0x91, 0x61, 0x91, 0x63, + 0x91, 0x65, 0x91, 0x69, 0x91, 0x6f, 0x91, 0x73, 0x91, 0x74}; +const uint8_t HuffDecoderCommon::table38_7_emit_[40] = { + 0x94, 0x30, 0x94, 0x31, 0x94, 0x32, 0x94, 0x61, 0x94, 0x63, + 0x94, 0x65, 0x94, 0x69, 0x94, 0x6f, 0x94, 0x73, 0x94, 0x74, + 0x9f, 0x30, 0x9f, 0x31, 0x9f, 0x32, 0x9f, 0x61, 0x9f, 0x63, + 0x9f, 0x65, 0x9f, 0x69, 0x9f, 0x6f, 0x9f, 0x73, 0x9f, 0x74}; +const uint8_t HuffDecoderCommon::table38_8_emit_[40] = { + 0xab, 0x30, 0xab, 0x31, 0xab, 0x32, 0xab, 0x61, 0xab, 0x63, + 0xab, 0x65, 0xab, 0x69, 0xab, 0x6f, 0xab, 0x73, 0xab, 0x74, + 0xce, 0x30, 0xce, 0x31, 0xce, 0x32, 0xce, 0x61, 0xce, 0x63, + 0xce, 0x65, 0xce, 0x69, 0xce, 0x6f, 0xce, 0x73, 0xce, 0x74}; +const uint8_t HuffDecoderCommon::table38_9_emit_[40] = { + 0xd7, 0x30, 0xd7, 0x31, 0xd7, 0x32, 0xd7, 0x61, 0xd7, 0x63, + 0xd7, 0x65, 0xd7, 0x69, 0xd7, 0x6f, 0xd7, 0x73, 0xd7, 0x74, + 0xe1, 0x30, 0xe1, 0x31, 0xe1, 0x32, 0xe1, 0x61, 0xe1, 0x63, + 0xe1, 0x65, 0xe1, 0x69, 0xe1, 0x6f, 0xe1, 0x73, 0xe1, 0x74}; +const uint8_t HuffDecoderCommon::table38_10_emit_[40] = { + 0xec, 0x30, 0xec, 0x31, 0xec, 0x32, 0xec, 0x61, 0xec, 0x63, + 0xec, 0x65, 0xec, 0x69, 0xec, 0x6f, 0xec, 0x73, 0xec, 0x74, + 0xed, 0x30, 0xed, 0x31, 0xed, 0x32, 0xed, 0x61, 0xed, 0x63, + 0xed, 0x65, 0xed, 0x69, 0xed, 0x6f, 0xed, 0x73, 0xed, 0x74}; +const uint8_t HuffDecoderCommon::table38_11_emit_[4] = {0xc7, 0xcf, 0xea, 0xeb}; +const uint16_t HuffDecoderCommon::table38_11_ops_[64] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000e}; +const uint8_t HuffDecoderCommon::table38_12_emit_[8] = {0xc0, 0xc1, 0xc8, 0xc9, + 0xca, 0xcd, 0xd2, 0xd5}; +const uint16_t HuffDecoderCommon::table38_12_ops_[64] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000e, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0012, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0016, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001e}; +const uint8_t HuffDecoderCommon::table38_13_emit_[9] = { + 0xda, 0xdb, 0xee, 0xf0, 0xf2, 0xf3, 0xff, 0xcb, 0xcc}; +const uint16_t HuffDecoderCommon::table38_13_ops_[64] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000e, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0012, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0016, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001a, + 0x0000, 0x0000, 0x0000, 0x001e, 0x0000, 0x0000, 0x0000, 0x0022}; +const uint8_t HuffDecoderCommon::table38_14_emit_[16] = { + 0xd3, 0xd4, 0xd6, 0xdd, 0xde, 0xdf, 0xf1, 0xf4, + 0xf5, 0xf6, 0xf7, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd}; +const uint16_t HuffDecoderCommon::table38_14_ops_[64] = { + 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0000, 0x0006, + 0x0000, 0x0000, 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x000e, + 0x0000, 0x0000, 0x0000, 0x0012, 0x0000, 0x0000, 0x0000, 0x0016, + 0x0000, 0x0000, 0x0000, 0x001a, 0x0000, 0x0000, 0x0000, 0x001e, + 0x0000, 0x0000, 0x0000, 0x0022, 0x0000, 0x0000, 0x0000, 0x0026, + 0x0000, 0x0000, 0x0000, 0x002a, 0x0000, 0x0000, 0x0000, 0x002e, + 0x0000, 0x0000, 0x0000, 0x0032, 0x0000, 0x0000, 0x0000, 0x0036, + 0x0000, 0x0000, 0x0000, 0x003a, 0x0000, 0x0000, 0x0000, 0x003e}; +const uint8_t HuffDecoderCommon::table38_15_emit_[30] = { + 0xfe, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0b, 0x0c, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x7f, 0xdc, 0xf9}; +const uint16_t HuffDecoderCommon::table38_15_ops_[64] = { + 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0006, 0x0000, 0x000a, + 0x0000, 0x000e, 0x0000, 0x0012, 0x0000, 0x0016, 0x0000, 0x001a, + 0x0000, 0x001e, 0x0000, 0x0022, 0x0000, 0x0026, 0x0000, 0x002a, + 0x0000, 0x002e, 0x0000, 0x0032, 0x0000, 0x0036, 0x0000, 0x003a, + 0x0000, 0x003e, 0x0000, 0x0042, 0x0000, 0x0046, 0x0000, 0x004a, + 0x0000, 0x004e, 0x0000, 0x0052, 0x0000, 0x0056, 0x0000, 0x005a, + 0x0000, 0x005e, 0x0000, 0x0062, 0x0000, 0x0066, 0x0000, 0x006a, + 0x0000, 0x006e, 0x0000, 0x0072, 0x0000, 0x0076, 0x0000, 0x0003}; +const uint8_t* const HuffDecoderCommon::table38_emit_[16] = { + table38_0_emit_, table38_1_emit_, table38_2_emit_, table38_3_emit_, + table38_4_emit_, table38_5_emit_, table38_6_emit_, table38_7_emit_, + table38_8_emit_, table38_9_emit_, table38_10_emit_, table38_11_emit_, + table38_12_emit_, table38_13_emit_, table38_14_emit_, table38_15_emit_, +}; +const uint16_t* const HuffDecoderCommon::table38_ops_[16] = { + table38_0_ops_, table38_0_ops_, table38_0_ops_, table38_0_ops_, + table38_0_ops_, table38_5_ops_, table38_5_ops_, table38_5_ops_, + table38_5_ops_, table38_5_ops_, table38_5_ops_, table38_11_ops_, + table38_12_ops_, table38_13_ops_, table38_14_ops_, table38_15_ops_, +}; +const uint8_t HuffDecoderCommon::table31_0_emit_[1] = {0xbc}; +const uint16_t HuffDecoderCommon::table31_0_ops_[64] = { + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004}; +const uint8_t HuffDecoderCommon::table31_2_emit_[1] = {0xbf}; +const uint8_t HuffDecoderCommon::table31_4_emit_[1] = {0xc5}; +const uint8_t HuffDecoderCommon::table31_6_emit_[1] = {0xe7}; +const uint8_t HuffDecoderCommon::table31_8_emit_[1] = {0xef}; +const uint8_t HuffDecoderCommon::table31_10_emit_[1] = {0x09}; +const uint16_t HuffDecoderCommon::table31_10_ops_[64] = { + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, - 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, - 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, - 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065}; -const uint8_t HuffDecoderCommon::table38_1_emit_[4] = {0xde, 0xdf, 0xf1, 0xf4}; -const uint8_t HuffDecoderCommon::table38_2_emit_[4] = {0xf5, 0xf6, 0xf7, 0xf8}; -const uint8_t HuffDecoderCommon::table38_3_emit_[4] = {0xfa, 0xfb, 0xfc, 0xfd}; -const uint8_t HuffDecoderCommon::table38_4_emit_[7] = {0xfe, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07}; -const uint16_t HuffDecoderCommon::table38_4_ops_[32] = { 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, - 0x0026, 0x0026, 0x0026, 0x0026, 0x0046, 0x0046, 0x0046, 0x0046, - 0x0066, 0x0066, 0x0066, 0x0066, 0x0086, 0x0086, 0x0086, 0x0086, - 0x00a6, 0x00a6, 0x00a6, 0x00a6, 0x00c6, 0x00c6, 0x00c6, 0x00c6}; -const uint8_t HuffDecoderCommon::table38_5_emit_[8] = {0x08, 0x0b, 0x0c, 0x0e, - 0x0f, 0x10, 0x11, 0x12}; -const uint16_t HuffDecoderCommon::table38_5_ops_[32] = { - 0x0006, 0x0006, 0x0006, 0x0006, 0x0026, 0x0026, 0x0026, 0x0026, - 0x0046, 0x0046, 0x0046, 0x0046, 0x0066, 0x0066, 0x0066, 0x0066, - 0x0086, 0x0086, 0x0086, 0x0086, 0x00a6, 0x00a6, 0x00a6, 0x00a6, - 0x00c6, 0x00c6, 0x00c6, 0x00c6, 0x00e6, 0x00e6, 0x00e6, 0x00e6}; -const uint8_t HuffDecoderCommon::table38_6_emit_[8] = {0x13, 0x14, 0x15, 0x17, - 0x18, 0x19, 0x1a, 0x1b}; -const uint8_t HuffDecoderCommon::table38_7_emit_[10] = { - 0x1c, 0x1d, 0x1e, 0x1f, 0x7f, 0xdc, 0xf9, 0x0a, 0x0d, 0x16}; -const uint16_t HuffDecoderCommon::table38_7_ops_[32] = { - 0x0006, 0x0006, 0x0006, 0x0006, 0x0026, 0x0026, 0x0026, 0x0026, - 0x0046, 0x0046, 0x0046, 0x0046, 0x0066, 0x0066, 0x0066, 0x0066, - 0x0086, 0x0086, 0x0086, 0x0086, 0x00a6, 0x00a6, 0x00a6, 0x00a6, - 0x00c6, 0x00c6, 0x00c6, 0x00c6, 0x00e8, 0x0108, 0x0128, 0x0018}; -const uint8_t* const HuffDecoderCommon::table38_emit_[8] = { - table38_0_emit_, table38_1_emit_, table38_2_emit_, table38_3_emit_, - table38_4_emit_, table38_5_emit_, table38_6_emit_, table38_7_emit_, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005}; +const uint8_t HuffDecoderCommon::table31_11_emit_[1] = {0x8e}; +const uint8_t HuffDecoderCommon::table31_12_emit_[1] = {0x90}; +const uint8_t HuffDecoderCommon::table31_13_emit_[1] = {0x91}; +const uint8_t HuffDecoderCommon::table31_14_emit_[1] = {0x94}; +const uint8_t HuffDecoderCommon::table31_15_emit_[1] = {0x9f}; +const uint8_t HuffDecoderCommon::table31_16_emit_[1] = {0xab}; +const uint8_t HuffDecoderCommon::table31_17_emit_[1] = {0xce}; +const uint8_t HuffDecoderCommon::table31_18_emit_[1] = {0xd7}; +const uint8_t HuffDecoderCommon::table31_19_emit_[1] = {0xe1}; +const uint8_t HuffDecoderCommon::table31_20_emit_[1] = {0xec}; +const uint8_t HuffDecoderCommon::table31_21_emit_[1] = {0xed}; +const uint8_t HuffDecoderCommon::table31_22_emit_[2] = {0xc7, 0xcf}; +const uint16_t HuffDecoderCommon::table31_22_ops_[64] = { + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, + 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, + 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, + 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026}; +const uint8_t HuffDecoderCommon::table31_23_emit_[2] = {0xea, 0xeb}; +const uint8_t HuffDecoderCommon::table31_24_emit_[4] = {0xc0, 0xc1, 0xc8, 0xc9}; +const uint16_t HuffDecoderCommon::table31_24_ops_[64] = { + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, + 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, + 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, + 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, + 0x0067, 0x0067, 0x0067, 0x0067, 0x0067, 0x0067, 0x0067, 0x0067, + 0x0067, 0x0067, 0x0067, 0x0067, 0x0067, 0x0067, 0x0067, 0x0067}; +const uint8_t HuffDecoderCommon::table31_25_emit_[4] = {0xca, 0xcd, 0xd2, 0xd5}; +const uint8_t HuffDecoderCommon::table31_26_emit_[4] = {0xda, 0xdb, 0xee, 0xf0}; +const uint8_t HuffDecoderCommon::table31_27_emit_[5] = {0xf2, 0xf3, 0xff, 0xcb, + 0xcc}; +const uint16_t HuffDecoderCommon::table31_27_ops_[64] = { + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, + 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, + 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, + 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, + 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, + 0x0088, 0x0088, 0x0088, 0x0088, 0x0088, 0x0088, 0x0088, 0x0088}; +const uint8_t HuffDecoderCommon::table31_28_emit_[8] = {0xd3, 0xd4, 0xd6, 0xdd, + 0xde, 0xdf, 0xf1, 0xf4}; +const uint16_t HuffDecoderCommon::table31_28_ops_[64] = { + 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, + 0x0048, 0x0048, 0x0048, 0x0048, 0x0048, 0x0048, 0x0048, 0x0048, + 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, 0x0068, + 0x0088, 0x0088, 0x0088, 0x0088, 0x0088, 0x0088, 0x0088, 0x0088, + 0x00a8, 0x00a8, 0x00a8, 0x00a8, 0x00a8, 0x00a8, 0x00a8, 0x00a8, + 0x00c8, 0x00c8, 0x00c8, 0x00c8, 0x00c8, 0x00c8, 0x00c8, 0x00c8, + 0x00e8, 0x00e8, 0x00e8, 0x00e8, 0x00e8, 0x00e8, 0x00e8, 0x00e8}; +const uint8_t HuffDecoderCommon::table31_29_emit_[8] = {0xf5, 0xf6, 0xf7, 0xf8, + 0xfa, 0xfb, 0xfc, 0xfd}; +const uint8_t HuffDecoderCommon::table31_30_emit_[15] = { + 0xfe, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12}; +const uint16_t HuffDecoderCommon::table31_30_ops_[64] = { + 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0029, 0x0029, 0x0029, 0x0029, 0x0049, 0x0049, 0x0049, 0x0049, + 0x0069, 0x0069, 0x0069, 0x0069, 0x0089, 0x0089, 0x0089, 0x0089, + 0x00a9, 0x00a9, 0x00a9, 0x00a9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, + 0x00e9, 0x00e9, 0x00e9, 0x00e9, 0x0109, 0x0109, 0x0109, 0x0109, + 0x0129, 0x0129, 0x0129, 0x0129, 0x0149, 0x0149, 0x0149, 0x0149, + 0x0169, 0x0169, 0x0169, 0x0169, 0x0189, 0x0189, 0x0189, 0x0189, + 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01c9, 0x01c9, 0x01c9, 0x01c9}; +const uint8_t HuffDecoderCommon::table31_31_emit_[18] = { + 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x7f, 0xdc, 0xf9, 0x0a, 0x0d, 0x16}; +const uint16_t HuffDecoderCommon::table31_31_ops_[64] = { + 0x0009, 0x0009, 0x0009, 0x0009, 0x0029, 0x0029, 0x0029, 0x0029, + 0x0049, 0x0049, 0x0049, 0x0049, 0x0069, 0x0069, 0x0069, 0x0069, + 0x0089, 0x0089, 0x0089, 0x0089, 0x00a9, 0x00a9, 0x00a9, 0x00a9, + 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00e9, 0x00e9, 0x00e9, 0x00e9, + 0x0109, 0x0109, 0x0109, 0x0109, 0x0129, 0x0129, 0x0129, 0x0129, + 0x0149, 0x0149, 0x0149, 0x0149, 0x0169, 0x0169, 0x0169, 0x0169, + 0x0189, 0x0189, 0x0189, 0x0189, 0x01a9, 0x01a9, 0x01a9, 0x01a9, + 0x01c9, 0x01c9, 0x01c9, 0x01c9, 0x01eb, 0x020b, 0x022b, 0x001b}; +const uint8_t* const HuffDecoderCommon::table31_emit_[32] = { + table31_0_emit_, table31_0_emit_, table31_2_emit_, table31_2_emit_, + table31_4_emit_, table31_4_emit_, table31_6_emit_, table31_6_emit_, + table31_8_emit_, table31_8_emit_, table31_10_emit_, table31_11_emit_, + table31_12_emit_, table31_13_emit_, table31_14_emit_, table31_15_emit_, + table31_16_emit_, table31_17_emit_, table31_18_emit_, table31_19_emit_, + table31_20_emit_, table31_21_emit_, table31_22_emit_, table31_23_emit_, + table31_24_emit_, table31_25_emit_, table31_26_emit_, table31_27_emit_, + table31_28_emit_, table31_29_emit_, table31_30_emit_, table31_31_emit_, }; -const uint16_t* const HuffDecoderCommon::table38_ops_[8] = { - table38_0_ops_, table38_0_ops_, table38_0_ops_, table38_0_ops_, - table38_4_ops_, table38_5_ops_, table38_5_ops_, table38_7_ops_, +const uint16_t* const HuffDecoderCommon::table31_ops_[32] = { + table31_0_ops_, table31_0_ops_, table31_0_ops_, table31_0_ops_, + table31_0_ops_, table31_0_ops_, table31_0_ops_, table31_0_ops_, + table31_0_ops_, table31_0_ops_, table31_10_ops_, table31_10_ops_, + table31_10_ops_, table31_10_ops_, table31_10_ops_, table31_10_ops_, + table31_10_ops_, table31_10_ops_, table31_10_ops_, table31_10_ops_, + table31_10_ops_, table31_10_ops_, table31_22_ops_, table31_22_ops_, + table31_24_ops_, table31_24_ops_, table31_24_ops_, table31_27_ops_, + table31_28_ops_, table31_28_ops_, table31_30_ops_, table31_31_ops_, }; } // namespace grpc_core diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.h b/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.h index 555c2da2683..375ec4a4870 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/decode_huff.h @@ -1,4 +1,4 @@ -// Copyright 2022 gRPC authors. +// Copyright 2023 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,193 +24,300 @@ namespace grpc_core { class HuffDecoderCommon { protected: - static inline uint64_t GetOp2(size_t i) { return table2_0_ops_[i]; } - static inline uint64_t GetEmit2(size_t, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp2(size_t i) { + return table2_0_ops_[i]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit2( + size_t, size_t emit) { return table2_0_emit_[emit]; } - static inline uint64_t GetOp3(size_t i) { return table3_0_ops_[i]; } - static inline uint64_t GetEmit3(size_t, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp3(size_t i) { + return table3_0_ops_[i]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit3( + size_t, size_t emit) { return table3_0_emit_[emit]; } - static inline uint64_t GetOp4(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp4(size_t i) { return table4_ops_[i >> 6][i & 0x3f]; } - static inline uint64_t GetEmit4(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit4( + size_t i, size_t emit) { return table4_emit_[i >> 6][emit]; } - static inline uint64_t GetOp5(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp5(size_t i) { return table5_ops_[i >> 7][i & 0x7f]; } - static inline uint64_t GetEmit5(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit5( + size_t i, size_t emit) { return table5_emit_[i >> 7][emit]; } - static inline uint64_t GetOp6(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp6(size_t i) { return table6_ops_[i >> 5][i & 0x1f]; } - static inline uint64_t GetEmit6(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit6( + size_t i, size_t emit) { return table6_emit_[i >> 5][emit]; } - static inline uint64_t GetOp7(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp7(size_t i) { return table7_ops_[i >> 6][i & 0x3f]; } - static inline uint64_t GetEmit7(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit7( + size_t i, size_t emit) { return table7_emit_[i >> 6][emit]; } - static inline uint64_t GetOp8(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp8(size_t i) { return table8_inner_[i >> 6][table8_outer_[i >> 6][i & 0x3f]]; } - static inline uint64_t GetEmit8(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit8( + size_t i, size_t emit) { return table8_emit_[i >> 6][emit]; } - static inline uint64_t GetOp9(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp9(size_t i) { return table9_ops_[i >> 5][i & 0x1f]; } - static inline uint64_t GetEmit9(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit9( + size_t i, size_t emit) { return table9_emit_[i >> 5][emit]; } - static inline uint64_t GetOp10(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp10( + size_t i) { return table10_inner_[i >> 6][table10_outer_[i >> 6][i & 0x3f]]; } - static inline uint64_t GetEmit10(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit10( + size_t i, size_t emit) { return table10_emit_[i >> 6][emit]; } - static inline uint64_t GetOp11(size_t i) { - return table11_inner_[i >> 6][table11_outer_[i >> 6][i & 0x3f]]; - } - static inline uint64_t GetEmit11(size_t i, size_t emit) { - return table11_emit_[i >> 6][emit]; - } - static inline uint64_t GetOp1(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp1(size_t i) { return table1_inner_[i >> 6][table1_outer_[i >> 6][i & 0x3f]]; } - static inline uint64_t GetEmit1(size_t i, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit1( + size_t i, size_t emit) { return table1_emit_[i >> 6][emit]; } - static inline uint64_t GetOp13(size_t i) { - return table13_0_inner_[(i < 3 ? (i) : (((i - 3) / 12) + 3))]; - } - static inline uint64_t GetEmit13(size_t, size_t emit) { - return (emit < 1 ? (((void)emit, 92)) : ((emit - 1) ? 208 : 195)); - } - static inline uint64_t GetOp14(size_t i) { return table14_0_ops_[i]; } - static inline uint64_t GetEmit14(size_t, size_t emit) { - return table14_0_emit_[emit]; - } - static inline uint64_t GetOp15(size_t i) { return table15_0_ops_[i]; } - static inline uint64_t GetEmit15(size_t, size_t emit) { - return table15_0_emit_[emit]; - } - static inline uint64_t GetOp12(size_t i) { - return table12_0_inner_[table12_0_outer_[i]]; - } - static inline uint64_t GetEmit12(size_t, size_t emit) { - return table12_0_emit_[emit]; - } - static inline uint64_t GetOp16(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit16(size_t, size_t emit) { - return emit ? 135 : 1; - } - static inline uint64_t GetOp17(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit17(size_t, size_t emit) { return emit + 137; } - static inline uint64_t GetOp18(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit18(size_t, size_t emit) { return emit + 139; } - static inline uint64_t GetOp19(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit19(size_t, size_t emit) { - return emit ? 143 : 141; - } - static inline uint64_t GetOp20(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit20(size_t, size_t emit) { - return emit ? 149 : 147; - } - static inline uint64_t GetOp21(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit21(size_t, size_t emit) { return emit + 150; } - static inline uint64_t GetOp22(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit22(size_t, size_t emit) { - return emit ? 155 : 152; - } - static inline uint64_t GetOp23(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit23(size_t, size_t emit) { return emit + 157; } - static inline uint64_t GetOp24(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit24(size_t, size_t emit) { return emit + 165; } - static inline uint64_t GetOp25(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit25(size_t, size_t emit) { - return emit ? 174 : 168; - } - static inline uint64_t GetOp26(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit26(size_t, size_t emit) { - return emit ? 180 : 175; - } - static inline uint64_t GetOp27(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit27(size_t, size_t emit) { return emit + 182; } - static inline uint64_t GetOp28(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit28(size_t, size_t emit) { - return emit ? 191 : 188; - } - static inline uint64_t GetOp29(size_t i) { return i ? 3 : 1; } - static inline uint64_t GetEmit29(size_t, size_t emit) { - return emit ? 231 : 197; - } - static inline uint64_t GetOp30(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp11( + size_t i) { + return i ? 3 : 1; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit11( + size_t, size_t emit) { + return emit ? 96 : 60; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp13( + size_t i) { + return i; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit13( + size_t, size_t emit) { + return ((void)emit, 123); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp14( + size_t i) { + return (i < 2 ? (i) : ((i - 2) ? 2 : 0)); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit14( + size_t, size_t emit) { + return ((void)emit, 123); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp15( + size_t i) { + return table15_0_outer_[i]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit15( + size_t, size_t emit) { + return ((void)emit, 123); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp16( + size_t i) { + return table16_0_outer_[i]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit16( + size_t, size_t emit) { + return ((void)emit, 123); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp12( + size_t i) { + return table12_0_inner_[(i < 15 ? (((void)i, 0)) : ((i - 15)))]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit12( + size_t, size_t emit) { + return (emit < 2 ? (emit ? 92 : 123) : ((emit - 2) ? 208 : 195)); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp17( + size_t i) { + return i ? 3 : 1; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit17( + size_t, size_t emit) { + return emit ? 130 : 128; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp18( + size_t i) { + return i ? 3 : 1; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit18( + size_t, size_t emit) { + return emit ? 162 : 131; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp19( + size_t i) { + return i ? 3 : 1; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit19( + size_t, size_t emit) { + return emit ? 194 : 184; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp20( + size_t i) { + return i ? 3 : 1; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit20( + size_t, size_t emit) { + return emit ? 226 : 224; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp21( + size_t i) { return (i < 2 ? (i ? 6 : 2) : ((i - 2) ? 14 : 10)); } - static inline uint64_t GetEmit30(size_t, size_t emit) { - return (emit < 2 ? (emit + 144) : ((emit - 2) ? 159 : 148)); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit21( + size_t, size_t emit) { + return (emit < 2 ? (emit ? 161 : 153) : ((emit - 2) ? 172 : 167)); } - static inline uint64_t GetOp31(size_t i) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp22( + size_t i) { return (i < 2 ? (i ? 6 : 2) : ((i - 2) ? 14 : 10)); } - static inline uint64_t GetEmit31(size_t, size_t emit) { - return (emit < 2 ? (emit ? 206 : 171) : ((emit - 2) ? 225 : 215)); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit22( + size_t, size_t emit) { + return (emit < 2 ? (emit + 176) : ((emit - 2) ? 209 : 179)); } - static inline uint64_t GetOp33(size_t i) { return table33_0_inner_[i]; } - static inline uint64_t GetEmit33(size_t, size_t emit) { - return table33_0_emit_[emit]; + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp23( + size_t i) { + return (i < 2 ? (i ? 6 : 2) : ((i - 2) ? 14 : 10)); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit23( + size_t, size_t emit) { + return (emit < 2 ? (emit + 216) : ((emit - 2) ? 229 : 227)); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp24( + size_t i) { + return table24_0_inner_[i]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit24( + size_t, size_t emit) { + return table24_0_emit_[emit]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp25( + size_t i) { + return table24_0_inner_[i]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit25( + size_t, size_t emit) { + return table25_0_emit_[emit]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp26( + size_t i) { + return table26_0_inner_[i]; } - static inline uint64_t GetOp32(size_t i) { return table32_0_ops_[i]; } - static inline uint64_t GetEmit32(size_t, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit26( + size_t, size_t emit) { + return table26_0_emit_[emit]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp28( + size_t i) { + return (i < 1 ? (((void)i, 0)) : (((void)(i - 1), 1))); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit28( + size_t, size_t emit) { + return ((void)emit, 230); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp27( + size_t i) { + return table27_0_inner_[(i < 1 ? (((void)i, 0)) : ((i - 1)))]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit27( + size_t, size_t emit) { + return table27_0_emit_[emit]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp30( + size_t i) { + return table30_0_inner_[(i < 4 ? (i) : (((void)(i - 4), 4)))]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit30( + size_t, size_t emit) { + return (emit < 2 ? (emit ? 228 : 198) : ((emit - 2) + 232)); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp29( + size_t i) { + return table29_0_inner_[(i < 7 ? (i / 2 + 0) : ((i - 7) + 3))]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit29( + size_t, size_t emit) { + return table29_0_emit_[emit]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp32( + size_t i) { + return table32_0_inner_[(i < 5 ? (i) : ((i - 5) / 10 + 5))]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit32( + size_t, size_t emit) { return table32_0_emit_[emit]; } - static inline uint64_t GetOp35(size_t i) { return i; } - static inline uint64_t GetEmit35(size_t, size_t emit) { - return ((void)emit, 239); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp33( + size_t i) { + return table33_0_ops_[i]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit33( + size_t, size_t emit) { + return table33_0_emit_[emit]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp34( + size_t i) { + return table34_0_ops_[i]; } - static inline uint64_t GetOp34(size_t i) { - return ((i < 1 ? (((void)i, 0)) : ((i - 1))) < 1 - ? (((void)(i < 1 ? (((void)i, 0)) : ((i - 1))), 1)) - : (((i < 1 ? (((void)i, 0)) : ((i - 1))) - 1) ? 10 : 6)); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit34( + size_t, size_t emit) { + return table34_0_emit_[emit]; } - static inline uint64_t GetEmit34(size_t, size_t emit) { - return (emit < 1 ? (((void)emit, 239)) : ((emit - 1) ? 142 : 9)); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp35( + size_t i) { + return table35_0_ops_[i]; } - static inline uint64_t GetOp37(size_t i) { - return ((i < 2 ? (i) : (((void)(i - 2), 2))) < 1 - ? (((void)(i < 2 ? (i) : (((void)(i - 2), 2))), 0)) - : (((i < 2 ? (i) : (((void)(i - 2), 2))) - 1) ? 1 : 2)); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit35( + size_t, size_t emit) { + return table35_0_emit_[emit]; } - static inline uint64_t GetEmit37(size_t, size_t emit) { return emit + 236; } - static inline uint64_t GetOp36(size_t i) { - return table36_0_inner_[(i < 3 ? ((i / 2) + 0) : ((i - 3) + 1))]; + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp36( + size_t i) { + return table36_0_ops_[i]; } - static inline uint64_t GetEmit36(size_t, size_t emit) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit36( + size_t, size_t emit) { return table36_0_emit_[emit]; } - static inline uint64_t GetOp39(size_t i) { return table39_0_ops_[i]; } - static inline uint64_t GetEmit39(size_t, size_t emit) { - return table39_0_emit_[emit]; + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp37( + size_t i) { + return table37_ops_[i >> 6][i & 0x3f]; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit37( + size_t i, size_t emit) { + return table37_emit_[i >> 6][emit]; } - static inline uint64_t GetOp40(size_t i) { return table40_0_ops_[i]; } - static inline uint64_t GetEmit40(size_t, size_t emit) { - return table40_0_emit_[emit]; + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp38( + size_t i) { + return table38_ops_[i >> 6][i & 0x3f]; } - static inline uint64_t GetOp41(size_t i) { return table41_0_ops_[i]; } - static inline uint64_t GetEmit41(size_t, size_t emit) { - return table40_0_emit_[emit]; + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit38( + size_t i, size_t emit) { + return table38_emit_[i >> 6][emit]; } - static inline uint64_t GetOp38(size_t i) { - return table38_ops_[i >> 5][i & 0x1f]; + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetOp31( + size_t i) { + return table31_ops_[i >> 6][i & 0x3f]; } - static inline uint64_t GetEmit38(size_t i, size_t emit) { - return table38_emit_[i >> 5][emit]; + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static inline uint64_t GetEmit31( + size_t i, size_t emit) { + return table31_emit_[i >> 6][emit]; } private: @@ -617,980 +724,452 @@ class HuffDecoderCommon { static const uint8_t* const table10_emit_[128]; static const uint16_t* const table10_inner_[128]; static const uint8_t* const table10_outer_[128]; - static const uint8_t table11_0_emit_[7]; - static const uint16_t table11_0_inner_[5]; - static const uint8_t table11_1_emit_[8]; - static const uint16_t table11_1_inner_[5]; - static const uint8_t table11_2_emit_[12]; - static const uint16_t table11_2_inner_[7]; - static const uint8_t table11_2_outer_[64]; - static const uint8_t table11_3_emit_[16]; - static const uint8_t table11_4_emit_[16]; - static const uint8_t table11_5_emit_[20]; - static const uint16_t table11_5_inner_[11]; - static const uint8_t table11_5_outer_[64]; - static const uint8_t table11_6_emit_[32]; - static const uint16_t table11_6_inner_[17]; - static const uint8_t table11_6_outer_[64]; - static const uint8_t table11_7_emit_[36]; - static const uint16_t table11_7_inner_[20]; - static const uint8_t table11_7_outer_[64]; - static const uint8_t table11_8_emit_[7]; - static const uint16_t table11_8_inner_[5]; - static const uint8_t table11_9_emit_[8]; - static const uint8_t table11_10_emit_[12]; - static const uint8_t table11_11_emit_[16]; - static const uint8_t table11_12_emit_[16]; - static const uint8_t table11_13_emit_[20]; - static const uint8_t table11_14_emit_[32]; - static const uint8_t table11_15_emit_[36]; - static const uint8_t table11_16_emit_[7]; - static const uint16_t table11_16_inner_[5]; - static const uint8_t table11_17_emit_[8]; - static const uint8_t table11_18_emit_[12]; - static const uint8_t table11_19_emit_[16]; - static const uint8_t table11_20_emit_[16]; - static const uint8_t table11_21_emit_[20]; - static const uint8_t table11_22_emit_[32]; - static const uint8_t table11_23_emit_[36]; - static const uint8_t table11_24_emit_[8]; - static const uint8_t table11_25_emit_[8]; - static const uint8_t table11_26_emit_[12]; - static const uint8_t table11_27_emit_[16]; - static const uint8_t table11_28_emit_[16]; - static const uint8_t table11_29_emit_[20]; - static const uint8_t table11_30_emit_[32]; - static const uint8_t table11_31_emit_[36]; - static const uint8_t table11_32_emit_[8]; - static const uint8_t table11_33_emit_[7]; - static const uint8_t table11_34_emit_[12]; - static const uint8_t table11_35_emit_[16]; - static const uint8_t table11_36_emit_[16]; - static const uint8_t table11_37_emit_[20]; - static const uint8_t table11_38_emit_[32]; - static const uint8_t table11_39_emit_[36]; - static const uint8_t table11_40_emit_[8]; - static const uint8_t table11_41_emit_[7]; - static const uint8_t table11_42_emit_[12]; - static const uint8_t table11_43_emit_[16]; - static const uint8_t table11_44_emit_[16]; - static const uint8_t table11_45_emit_[20]; - static const uint8_t table11_46_emit_[32]; - static const uint8_t table11_47_emit_[36]; - static const uint8_t table11_48_emit_[8]; - static const uint8_t table11_49_emit_[7]; - static const uint8_t table11_50_emit_[12]; - static const uint8_t table11_51_emit_[16]; - static const uint8_t table11_52_emit_[16]; - static const uint8_t table11_53_emit_[20]; - static const uint8_t table11_54_emit_[32]; - static const uint8_t table11_55_emit_[36]; - static const uint8_t table11_56_emit_[8]; - static const uint8_t table11_57_emit_[8]; - static const uint8_t table11_58_emit_[12]; - static const uint8_t table11_59_emit_[16]; - static const uint8_t table11_60_emit_[16]; - static const uint8_t table11_61_emit_[20]; - static const uint8_t table11_62_emit_[32]; - static const uint8_t table11_63_emit_[36]; - static const uint8_t table11_64_emit_[8]; - static const uint8_t table11_65_emit_[8]; - static const uint8_t table11_66_emit_[11]; - static const uint16_t table11_66_inner_[7]; - static const uint8_t table11_67_emit_[16]; - static const uint8_t table11_68_emit_[16]; - static const uint8_t table11_69_emit_[20]; - static const uint8_t table11_70_emit_[32]; - static const uint8_t table11_71_emit_[36]; - static const uint8_t table11_72_emit_[8]; - static const uint8_t table11_73_emit_[8]; - static const uint8_t table11_74_emit_[11]; - static const uint16_t table11_74_inner_[7]; - static const uint8_t table11_75_emit_[16]; - static const uint8_t table11_76_emit_[16]; - static const uint8_t table11_77_emit_[20]; - static const uint8_t table11_78_emit_[32]; - static const uint8_t table11_79_emit_[36]; - static const uint8_t table11_80_emit_[16]; - static const uint8_t table11_81_emit_[27]; - static const uint16_t table11_81_inner_[15]; - static const uint8_t table11_82_emit_[36]; - static const uint8_t table11_83_emit_[68]; - static const uint8_t table11_84_emit_[16]; - static const uint8_t table11_85_emit_[27]; - static const uint16_t table11_85_inner_[15]; - static const uint8_t table11_86_emit_[36]; - static const uint8_t table11_87_emit_[68]; - static const uint8_t table11_88_emit_[16]; - static const uint8_t table11_89_emit_[27]; - static const uint16_t table11_89_inner_[15]; - static const uint8_t table11_90_emit_[36]; - static const uint8_t table11_91_emit_[68]; - static const uint8_t table11_92_emit_[16]; - static const uint8_t table11_93_emit_[27]; - static const uint16_t table11_93_inner_[15]; - static const uint8_t table11_94_emit_[36]; - static const uint8_t table11_95_emit_[68]; - static const uint8_t table11_96_emit_[16]; - static const uint8_t table11_97_emit_[27]; - static const uint16_t table11_97_inner_[15]; - static const uint8_t table11_98_emit_[36]; - static const uint8_t table11_99_emit_[68]; - static const uint8_t table11_100_emit_[16]; - static const uint8_t table11_101_emit_[27]; - static const uint16_t table11_101_inner_[15]; - static const uint8_t table11_102_emit_[36]; - static const uint8_t table11_103_emit_[68]; - static const uint8_t table11_104_emit_[16]; - static const uint8_t table11_105_emit_[27]; - static const uint16_t table11_105_inner_[15]; - static const uint8_t table11_106_emit_[36]; - static const uint8_t table11_107_emit_[68]; - static const uint8_t table11_108_emit_[16]; - static const uint8_t table11_109_emit_[27]; - static const uint16_t table11_109_inner_[15]; - static const uint8_t table11_110_emit_[36]; - static const uint8_t table11_111_emit_[68]; - static const uint8_t table11_112_emit_[16]; - static const uint8_t table11_113_emit_[27]; - static const uint16_t table11_113_inner_[15]; - static const uint8_t table11_114_emit_[36]; - static const uint8_t table11_115_emit_[68]; - static const uint8_t table11_116_emit_[16]; - static const uint8_t table11_117_emit_[27]; - static const uint16_t table11_117_inner_[15]; - static const uint8_t table11_118_emit_[36]; - static const uint8_t table11_119_emit_[68]; - static const uint8_t table11_120_emit_[16]; - static const uint8_t table11_121_emit_[27]; - static const uint16_t table11_121_inner_[15]; - static const uint8_t table11_122_emit_[36]; - static const uint8_t table11_123_emit_[68]; - static const uint8_t table11_124_emit_[16]; - static const uint8_t table11_125_emit_[28]; - static const uint8_t table11_126_emit_[36]; - static const uint8_t table11_127_emit_[68]; - static const uint8_t table11_128_emit_[16]; - static const uint8_t table11_129_emit_[28]; - static const uint8_t table11_130_emit_[35]; - static const uint16_t table11_130_inner_[19]; - static const uint8_t table11_131_emit_[68]; - static const uint8_t table11_132_emit_[16]; - static const uint8_t table11_133_emit_[28]; - static const uint8_t table11_134_emit_[35]; - static const uint16_t table11_134_inner_[19]; - static const uint8_t table11_135_emit_[68]; - static const uint8_t table11_136_emit_[16]; - static const uint8_t table11_137_emit_[28]; - static const uint8_t table11_138_emit_[35]; - static const uint16_t table11_138_inner_[19]; - static const uint8_t table11_139_emit_[68]; - static const uint8_t table11_140_emit_[16]; - static const uint8_t table11_141_emit_[28]; - static const uint8_t table11_142_emit_[35]; - static const uint16_t table11_142_inner_[19]; - static const uint8_t table11_143_emit_[68]; - static const uint8_t table11_144_emit_[16]; - static const uint8_t table11_145_emit_[28]; - static const uint8_t table11_146_emit_[35]; - static const uint16_t table11_146_inner_[19]; - static const uint8_t table11_147_emit_[68]; - static const uint8_t table11_148_emit_[16]; - static const uint8_t table11_149_emit_[28]; - static const uint8_t table11_150_emit_[35]; - static const uint16_t table11_150_inner_[19]; - static const uint8_t table11_151_emit_[68]; - static const uint8_t table11_152_emit_[16]; - static const uint8_t table11_153_emit_[28]; - static const uint8_t table11_154_emit_[35]; - static const uint16_t table11_154_inner_[19]; - static const uint8_t table11_155_emit_[68]; - static const uint8_t table11_156_emit_[16]; - static const uint8_t table11_157_emit_[28]; - static const uint8_t table11_158_emit_[35]; - static const uint16_t table11_158_inner_[19]; - static const uint8_t table11_159_emit_[68]; - static const uint8_t table11_160_emit_[16]; - static const uint8_t table11_161_emit_[28]; - static const uint8_t table11_162_emit_[35]; - static const uint16_t table11_162_inner_[19]; - static const uint8_t table11_163_emit_[68]; - static const uint8_t table11_164_emit_[16]; - static const uint8_t table11_165_emit_[28]; - static const uint8_t table11_166_emit_[35]; - static const uint16_t table11_166_inner_[19]; - static const uint8_t table11_167_emit_[68]; - static const uint8_t table11_168_emit_[16]; - static const uint8_t table11_169_emit_[28]; - static const uint8_t table11_170_emit_[35]; - static const uint16_t table11_170_inner_[19]; - static const uint8_t table11_171_emit_[68]; - static const uint8_t table11_172_emit_[16]; - static const uint8_t table11_173_emit_[28]; - static const uint8_t table11_174_emit_[35]; - static const uint16_t table11_174_inner_[19]; - static const uint8_t table11_175_emit_[68]; - static const uint8_t table11_176_emit_[16]; - static const uint8_t table11_177_emit_[28]; - static const uint8_t table11_178_emit_[35]; - static const uint16_t table11_178_inner_[19]; - static const uint8_t table11_179_emit_[68]; - static const uint8_t table11_180_emit_[16]; - static const uint8_t table11_181_emit_[28]; - static const uint8_t table11_182_emit_[35]; - static const uint16_t table11_182_inner_[19]; - static const uint8_t table11_183_emit_[68]; - static const uint8_t table11_184_emit_[44]; - static const uint8_t table11_185_emit_[91]; - static const uint16_t table11_185_inner_[48]; - static const uint8_t table11_186_emit_[44]; - static const uint8_t table11_187_emit_[91]; - static const uint16_t table11_187_inner_[48]; - static const uint8_t table11_188_emit_[44]; - static const uint8_t table11_189_emit_[91]; - static const uint16_t table11_189_inner_[48]; - static const uint8_t table11_190_emit_[44]; - static const uint8_t table11_191_emit_[91]; - static const uint16_t table11_191_inner_[48]; - static const uint8_t table11_192_emit_[44]; - static const uint8_t table11_193_emit_[91]; - static const uint16_t table11_193_inner_[48]; - static const uint8_t table11_194_emit_[44]; - static const uint8_t table11_195_emit_[91]; - static const uint16_t table11_195_inner_[48]; - static const uint8_t table11_196_emit_[44]; - static const uint8_t table11_197_emit_[91]; - static const uint16_t table11_197_inner_[48]; - static const uint8_t table11_198_emit_[44]; - static const uint8_t table11_199_emit_[91]; - static const uint16_t table11_199_inner_[48]; - static const uint8_t table11_200_emit_[44]; - static const uint8_t table11_201_emit_[91]; - static const uint16_t table11_201_inner_[48]; - static const uint8_t table11_202_emit_[44]; - static const uint8_t table11_203_emit_[91]; - static const uint16_t table11_203_inner_[48]; - static const uint8_t table11_204_emit_[44]; - static const uint8_t table11_205_emit_[91]; - static const uint16_t table11_205_inner_[48]; - static const uint8_t table11_206_emit_[44]; - static const uint8_t table11_207_emit_[91]; - static const uint16_t table11_207_inner_[48]; - static const uint8_t table11_208_emit_[44]; - static const uint8_t table11_209_emit_[91]; - static const uint16_t table11_209_inner_[48]; - static const uint8_t table11_210_emit_[44]; - static const uint8_t table11_211_emit_[91]; - static const uint16_t table11_211_inner_[48]; - static const uint8_t table11_212_emit_[44]; - static const uint8_t table11_213_emit_[91]; - static const uint16_t table11_213_inner_[48]; - static const uint8_t table11_214_emit_[44]; - static const uint8_t table11_215_emit_[91]; - static const uint16_t table11_215_inner_[48]; - static const uint8_t table11_216_emit_[44]; - static const uint8_t table11_217_emit_[91]; - static const uint16_t table11_217_inner_[48]; - static const uint8_t table11_218_emit_[44]; - static const uint8_t table11_219_emit_[91]; - static const uint16_t table11_219_inner_[48]; - static const uint8_t table11_220_emit_[44]; - static const uint8_t table11_221_emit_[91]; - static const uint16_t table11_221_inner_[48]; - static const uint8_t table11_222_emit_[44]; - static const uint8_t table11_223_emit_[91]; - static const uint16_t table11_223_inner_[48]; - static const uint8_t table11_224_emit_[44]; - static const uint8_t table11_225_emit_[91]; - static const uint16_t table11_225_inner_[48]; - static const uint8_t table11_226_emit_[44]; - static const uint8_t table11_227_emit_[91]; - static const uint16_t table11_227_inner_[48]; - static const uint8_t table11_228_emit_[44]; - static const uint8_t table11_229_emit_[91]; - static const uint16_t table11_229_inner_[48]; - static const uint8_t table11_230_emit_[44]; - static const uint8_t table11_231_emit_[91]; - static const uint16_t table11_231_inner_[48]; - static const uint8_t table11_232_emit_[44]; - static const uint8_t table11_233_emit_[91]; - static const uint16_t table11_233_inner_[48]; - static const uint8_t table11_234_emit_[44]; - static const uint8_t table11_235_emit_[91]; - static const uint16_t table11_235_inner_[48]; - static const uint8_t table11_236_emit_[44]; - static const uint8_t table11_237_emit_[91]; - static const uint16_t table11_237_inner_[48]; - static const uint8_t table11_238_emit_[44]; - static const uint8_t table11_239_emit_[91]; - static const uint16_t table11_239_inner_[48]; - static const uint8_t table11_240_emit_[44]; - static const uint8_t table11_241_emit_[91]; - static const uint16_t table11_241_inner_[48]; - static const uint8_t table11_242_emit_[44]; - static const uint8_t table11_243_emit_[91]; - static const uint16_t table11_243_inner_[48]; - static const uint8_t table11_244_emit_[44]; - static const uint8_t table11_245_emit_[91]; - static const uint16_t table11_245_inner_[48]; - static const uint8_t table11_246_emit_[44]; - static const uint8_t table11_247_emit_[92]; - static const uint8_t table11_248_emit_[72]; - static const uint8_t table11_249_emit_[72]; - static const uint8_t table11_250_emit_[72]; - static const uint8_t table11_251_emit_[72]; - static const uint8_t table11_252_emit_[72]; - static const uint8_t table11_253_emit_[72]; - static const uint8_t table11_254_emit_[4]; - static const uint8_t table11_255_emit_[14]; - static const uint8_t table11_255_outer_[64]; - static const uint8_t* const table11_emit_[256]; - static const uint16_t* const table11_inner_[256]; - static const uint8_t* const table11_outer_[256]; - static const uint8_t table1_0_emit_[55]; - static const uint16_t table1_0_inner_[22]; + static const uint8_t table1_0_emit_[7]; + static const uint16_t table1_0_inner_[4]; static const uint8_t table1_0_outer_[64]; - static const uint8_t table1_1_emit_[58]; - static const uint16_t table1_1_inner_[22]; - static const uint8_t table1_2_emit_[58]; - static const uint8_t table1_3_emit_[58]; - static const uint8_t table1_4_emit_[58]; - static const uint8_t table1_5_emit_[8]; - static const uint16_t table1_5_inner_[4]; + static const uint8_t table1_1_emit_[8]; + static const uint16_t table1_1_inner_[4]; + static const uint8_t table1_2_emit_[12]; + static const uint16_t table1_2_inner_[6]; + static const uint8_t table1_2_outer_[64]; + static const uint8_t table1_3_emit_[16]; + static const uint16_t table1_3_inner_[8]; + static const uint8_t table1_3_outer_[64]; + static const uint8_t table1_4_emit_[16]; + static const uint8_t table1_5_emit_[20]; + static const uint16_t table1_5_inner_[10]; static const uint8_t table1_5_outer_[64]; - static const uint8_t table1_6_emit_[8]; - static const uint8_t table1_7_emit_[8]; - static const uint8_t table1_8_emit_[8]; + static const uint8_t table1_6_emit_[32]; + static const uint16_t table1_6_inner_[16]; + static const uint8_t table1_6_outer_[64]; + static const uint8_t table1_7_emit_[36]; + static const uint16_t table1_7_inner_[19]; + static const uint8_t table1_7_outer_[64]; + static const uint8_t table1_8_emit_[7]; + static const uint16_t table1_8_inner_[4]; static const uint8_t table1_9_emit_[8]; - static const uint8_t table1_10_emit_[8]; - static const uint8_t table1_11_emit_[12]; - static const uint16_t table1_11_inner_[6]; - static const uint8_t table1_11_outer_[64]; + static const uint8_t table1_10_emit_[12]; + static const uint8_t table1_11_emit_[16]; static const uint8_t table1_12_emit_[16]; - static const uint16_t table1_12_inner_[8]; - static const uint8_t table1_12_outer_[64]; - static const uint8_t table1_13_emit_[16]; - static const uint8_t table1_14_emit_[16]; - static const uint8_t table1_15_emit_[30]; - static const uint16_t table1_15_inner_[16]; - static const uint8_t table1_15_outer_[64]; - static const uint8_t table1_16_emit_[57]; - static const uint16_t table1_16_inner_[22]; - static const uint8_t table1_17_emit_[58]; - static const uint16_t table1_17_inner_[22]; - static const uint8_t table1_18_emit_[58]; - static const uint8_t table1_19_emit_[58]; - static const uint8_t table1_20_emit_[58]; - static const uint8_t table1_21_emit_[8]; - static const uint8_t table1_22_emit_[8]; - static const uint8_t table1_23_emit_[8]; + static const uint8_t table1_13_emit_[20]; + static const uint8_t table1_14_emit_[32]; + static const uint8_t table1_15_emit_[36]; + static const uint8_t table1_16_emit_[7]; + static const uint16_t table1_16_inner_[4]; + static const uint8_t table1_17_emit_[8]; + static const uint8_t table1_18_emit_[12]; + static const uint8_t table1_19_emit_[16]; + static const uint8_t table1_20_emit_[16]; + static const uint8_t table1_21_emit_[20]; + static const uint8_t table1_22_emit_[32]; + static const uint8_t table1_23_emit_[36]; static const uint8_t table1_24_emit_[8]; static const uint8_t table1_25_emit_[8]; - static const uint8_t table1_26_emit_[8]; - static const uint8_t table1_27_emit_[12]; + static const uint8_t table1_26_emit_[12]; + static const uint8_t table1_27_emit_[16]; static const uint8_t table1_28_emit_[16]; - static const uint8_t table1_29_emit_[16]; - static const uint8_t table1_30_emit_[16]; - static const uint8_t table1_31_emit_[30]; - static const uint8_t table1_32_emit_[58]; - static const uint16_t table1_32_inner_[22]; - static const uint8_t table1_33_emit_[55]; - static const uint16_t table1_33_inner_[22]; - static const uint8_t table1_34_emit_[58]; - static const uint8_t table1_35_emit_[58]; - static const uint8_t table1_36_emit_[58]; - static const uint8_t table1_37_emit_[8]; - static const uint8_t table1_38_emit_[8]; - static const uint8_t table1_39_emit_[8]; + static const uint8_t table1_29_emit_[20]; + static const uint8_t table1_30_emit_[32]; + static const uint8_t table1_31_emit_[36]; + static const uint8_t table1_32_emit_[8]; + static const uint8_t table1_33_emit_[7]; + static const uint8_t table1_34_emit_[12]; + static const uint8_t table1_35_emit_[16]; + static const uint8_t table1_36_emit_[16]; + static const uint8_t table1_37_emit_[20]; + static const uint8_t table1_38_emit_[32]; + static const uint8_t table1_39_emit_[36]; static const uint8_t table1_40_emit_[8]; - static const uint8_t table1_41_emit_[8]; - static const uint8_t table1_42_emit_[8]; - static const uint8_t table1_43_emit_[12]; + static const uint8_t table1_41_emit_[7]; + static const uint8_t table1_42_emit_[12]; + static const uint8_t table1_43_emit_[16]; static const uint8_t table1_44_emit_[16]; - static const uint8_t table1_45_emit_[16]; - static const uint8_t table1_46_emit_[16]; - static const uint8_t table1_47_emit_[30]; - static const uint8_t table1_48_emit_[58]; - static const uint16_t table1_48_inner_[22]; - static const uint8_t table1_49_emit_[57]; - static const uint16_t table1_49_inner_[22]; - static const uint8_t table1_50_emit_[58]; - static const uint8_t table1_51_emit_[58]; - static const uint8_t table1_52_emit_[58]; - static const uint8_t table1_53_emit_[8]; - static const uint8_t table1_54_emit_[8]; - static const uint8_t table1_55_emit_[8]; + static const uint8_t table1_45_emit_[20]; + static const uint8_t table1_46_emit_[32]; + static const uint8_t table1_47_emit_[36]; + static const uint8_t table1_48_emit_[8]; + static const uint8_t table1_49_emit_[7]; + static const uint8_t table1_50_emit_[12]; + static const uint8_t table1_51_emit_[16]; + static const uint8_t table1_52_emit_[16]; + static const uint8_t table1_53_emit_[20]; + static const uint8_t table1_54_emit_[32]; + static const uint8_t table1_55_emit_[36]; static const uint8_t table1_56_emit_[8]; static const uint8_t table1_57_emit_[8]; - static const uint8_t table1_58_emit_[8]; - static const uint8_t table1_59_emit_[12]; + static const uint8_t table1_58_emit_[12]; + static const uint8_t table1_59_emit_[16]; static const uint8_t table1_60_emit_[16]; - static const uint8_t table1_61_emit_[16]; - static const uint8_t table1_62_emit_[16]; - static const uint8_t table1_63_emit_[30]; - static const uint8_t table1_64_emit_[58]; - static const uint16_t table1_64_inner_[22]; - static const uint8_t table1_65_emit_[58]; - static const uint8_t table1_66_emit_[55]; - static const uint16_t table1_66_inner_[22]; - static const uint8_t table1_67_emit_[58]; - static const uint8_t table1_68_emit_[58]; - static const uint8_t table1_69_emit_[8]; - static const uint8_t table1_70_emit_[8]; - static const uint8_t table1_71_emit_[8]; + static const uint8_t table1_61_emit_[20]; + static const uint8_t table1_62_emit_[32]; + static const uint8_t table1_63_emit_[36]; + static const uint8_t table1_64_emit_[8]; + static const uint8_t table1_65_emit_[8]; + static const uint8_t table1_66_emit_[11]; + static const uint16_t table1_66_inner_[6]; + static const uint8_t table1_67_emit_[16]; + static const uint8_t table1_68_emit_[16]; + static const uint8_t table1_69_emit_[20]; + static const uint8_t table1_70_emit_[32]; + static const uint8_t table1_71_emit_[36]; static const uint8_t table1_72_emit_[8]; static const uint8_t table1_73_emit_[8]; - static const uint8_t table1_74_emit_[8]; - static const uint8_t table1_75_emit_[12]; + static const uint8_t table1_74_emit_[11]; + static const uint16_t table1_74_inner_[6]; + static const uint8_t table1_75_emit_[16]; static const uint8_t table1_76_emit_[16]; - static const uint8_t table1_77_emit_[16]; - static const uint8_t table1_78_emit_[16]; - static const uint8_t table1_79_emit_[30]; - static const uint8_t table1_80_emit_[58]; - static const uint16_t table1_80_inner_[22]; - static const uint8_t table1_81_emit_[58]; - static const uint8_t table1_82_emit_[57]; - static const uint16_t table1_82_inner_[22]; - static const uint8_t table1_83_emit_[58]; - static const uint8_t table1_84_emit_[58]; - static const uint8_t table1_85_emit_[8]; - static const uint8_t table1_86_emit_[8]; - static const uint8_t table1_87_emit_[8]; - static const uint8_t table1_88_emit_[8]; - static const uint8_t table1_89_emit_[8]; - static const uint8_t table1_90_emit_[8]; - static const uint8_t table1_91_emit_[12]; + static const uint8_t table1_77_emit_[20]; + static const uint8_t table1_78_emit_[32]; + static const uint8_t table1_79_emit_[36]; + static const uint8_t table1_80_emit_[16]; + static const uint8_t table1_81_emit_[27]; + static const uint16_t table1_81_inner_[14]; + static const uint8_t table1_81_outer_[64]; + static const uint8_t table1_82_emit_[36]; + static const uint16_t table1_82_inner_[18]; + static const uint8_t table1_82_outer_[64]; + static const uint8_t table1_83_emit_[68]; + static const uint16_t table1_83_inner_[35]; + static const uint8_t table1_83_outer_[64]; + static const uint8_t table1_84_emit_[16]; + static const uint8_t table1_85_emit_[27]; + static const uint16_t table1_85_inner_[14]; + static const uint8_t table1_86_emit_[36]; + static const uint8_t table1_87_emit_[68]; + static const uint8_t table1_88_emit_[16]; + static const uint8_t table1_89_emit_[27]; + static const uint16_t table1_89_inner_[14]; + static const uint8_t table1_90_emit_[36]; + static const uint8_t table1_91_emit_[68]; static const uint8_t table1_92_emit_[16]; - static const uint8_t table1_93_emit_[16]; - static const uint8_t table1_94_emit_[16]; - static const uint8_t table1_95_emit_[30]; - static const uint8_t table1_96_emit_[58]; - static const uint16_t table1_96_inner_[22]; - static const uint8_t table1_97_emit_[58]; - static const uint8_t table1_98_emit_[58]; - static const uint8_t table1_99_emit_[55]; - static const uint16_t table1_99_inner_[22]; - static const uint8_t table1_100_emit_[58]; - static const uint8_t table1_101_emit_[8]; - static const uint8_t table1_102_emit_[8]; - static const uint8_t table1_103_emit_[8]; - static const uint8_t table1_104_emit_[8]; - static const uint8_t table1_105_emit_[8]; - static const uint8_t table1_106_emit_[8]; - static const uint8_t table1_107_emit_[12]; + static const uint8_t table1_93_emit_[27]; + static const uint16_t table1_93_inner_[14]; + static const uint8_t table1_94_emit_[36]; + static const uint8_t table1_95_emit_[68]; + static const uint8_t table1_96_emit_[16]; + static const uint8_t table1_97_emit_[27]; + static const uint16_t table1_97_inner_[14]; + static const uint8_t table1_98_emit_[36]; + static const uint8_t table1_99_emit_[68]; + static const uint8_t table1_100_emit_[16]; + static const uint8_t table1_101_emit_[27]; + static const uint16_t table1_101_inner_[14]; + static const uint8_t table1_102_emit_[36]; + static const uint8_t table1_103_emit_[68]; + static const uint8_t table1_104_emit_[16]; + static const uint8_t table1_105_emit_[27]; + static const uint16_t table1_105_inner_[14]; + static const uint8_t table1_106_emit_[36]; + static const uint8_t table1_107_emit_[68]; static const uint8_t table1_108_emit_[16]; - static const uint8_t table1_109_emit_[16]; - static const uint8_t table1_110_emit_[16]; - static const uint8_t table1_111_emit_[30]; - static const uint8_t table1_112_emit_[58]; - static const uint16_t table1_112_inner_[22]; - static const uint8_t table1_113_emit_[58]; - static const uint8_t table1_114_emit_[58]; - static const uint8_t table1_115_emit_[57]; - static const uint16_t table1_115_inner_[22]; - static const uint8_t table1_116_emit_[58]; - static const uint8_t table1_117_emit_[8]; - static const uint8_t table1_118_emit_[8]; - static const uint8_t table1_119_emit_[8]; - static const uint8_t table1_120_emit_[8]; - static const uint8_t table1_121_emit_[8]; - static const uint8_t table1_122_emit_[8]; - static const uint8_t table1_123_emit_[12]; + static const uint8_t table1_109_emit_[27]; + static const uint16_t table1_109_inner_[14]; + static const uint8_t table1_110_emit_[36]; + static const uint8_t table1_111_emit_[68]; + static const uint8_t table1_112_emit_[16]; + static const uint8_t table1_113_emit_[27]; + static const uint16_t table1_113_inner_[14]; + static const uint8_t table1_114_emit_[36]; + static const uint8_t table1_115_emit_[68]; + static const uint8_t table1_116_emit_[16]; + static const uint8_t table1_117_emit_[27]; + static const uint16_t table1_117_inner_[14]; + static const uint8_t table1_118_emit_[36]; + static const uint8_t table1_119_emit_[68]; + static const uint8_t table1_120_emit_[16]; + static const uint8_t table1_121_emit_[27]; + static const uint16_t table1_121_inner_[14]; + static const uint8_t table1_122_emit_[36]; + static const uint8_t table1_123_emit_[68]; static const uint8_t table1_124_emit_[16]; - static const uint8_t table1_125_emit_[16]; - static const uint8_t table1_126_emit_[16]; - static const uint8_t table1_127_emit_[30]; - static const uint8_t table1_128_emit_[58]; - static const uint16_t table1_128_inner_[22]; - static const uint8_t table1_129_emit_[58]; - static const uint8_t table1_130_emit_[58]; - static const uint8_t table1_131_emit_[58]; - static const uint8_t table1_132_emit_[55]; - static const uint16_t table1_132_inner_[22]; - static const uint8_t table1_133_emit_[8]; - static const uint8_t table1_134_emit_[8]; - static const uint8_t table1_135_emit_[8]; - static const uint8_t table1_136_emit_[8]; - static const uint8_t table1_137_emit_[8]; - static const uint8_t table1_138_emit_[8]; - static const uint8_t table1_139_emit_[12]; + static const uint8_t table1_125_emit_[28]; + static const uint16_t table1_125_inner_[14]; + static const uint8_t table1_126_emit_[36]; + static const uint8_t table1_127_emit_[68]; + static const uint8_t table1_128_emit_[16]; + static const uint8_t table1_129_emit_[28]; + static const uint8_t table1_130_emit_[35]; + static const uint16_t table1_130_inner_[18]; + static const uint8_t table1_131_emit_[68]; + static const uint8_t table1_132_emit_[16]; + static const uint8_t table1_133_emit_[28]; + static const uint8_t table1_134_emit_[35]; + static const uint16_t table1_134_inner_[18]; + static const uint8_t table1_135_emit_[68]; + static const uint8_t table1_136_emit_[16]; + static const uint8_t table1_137_emit_[28]; + static const uint8_t table1_138_emit_[35]; + static const uint16_t table1_138_inner_[18]; + static const uint8_t table1_139_emit_[68]; static const uint8_t table1_140_emit_[16]; - static const uint8_t table1_141_emit_[16]; - static const uint8_t table1_142_emit_[16]; - static const uint8_t table1_143_emit_[30]; - static const uint8_t table1_144_emit_[59]; - static const uint16_t table1_144_inner_[22]; - static const uint8_t table1_145_emit_[59]; - static const uint8_t table1_146_emit_[59]; - static const uint8_t table1_147_emit_[59]; - static const uint8_t table1_148_emit_[59]; - static const uint8_t table1_149_emit_[8]; - static const uint8_t table1_150_emit_[8]; - static const uint8_t table1_151_emit_[8]; - static const uint8_t table1_152_emit_[8]; - static const uint8_t table1_153_emit_[8]; - static const uint8_t table1_154_emit_[8]; - static const uint8_t table1_155_emit_[12]; + static const uint8_t table1_141_emit_[28]; + static const uint8_t table1_142_emit_[35]; + static const uint16_t table1_142_inner_[18]; + static const uint8_t table1_143_emit_[68]; + static const uint8_t table1_144_emit_[16]; + static const uint8_t table1_145_emit_[28]; + static const uint8_t table1_146_emit_[35]; + static const uint16_t table1_146_inner_[18]; + static const uint8_t table1_147_emit_[68]; + static const uint8_t table1_148_emit_[16]; + static const uint8_t table1_149_emit_[28]; + static const uint8_t table1_150_emit_[35]; + static const uint16_t table1_150_inner_[18]; + static const uint8_t table1_151_emit_[68]; + static const uint8_t table1_152_emit_[16]; + static const uint8_t table1_153_emit_[28]; + static const uint8_t table1_154_emit_[35]; + static const uint16_t table1_154_inner_[18]; + static const uint8_t table1_155_emit_[68]; static const uint8_t table1_156_emit_[16]; - static const uint8_t table1_157_emit_[16]; - static const uint8_t table1_158_emit_[16]; - static const uint8_t table1_159_emit_[30]; - static const uint8_t table1_160_emit_[8]; - static const uint8_t table1_161_emit_[8]; - static const uint8_t table1_162_emit_[11]; - static const uint16_t table1_162_inner_[6]; - static const uint8_t table1_163_emit_[16]; + static const uint8_t table1_157_emit_[28]; + static const uint8_t table1_158_emit_[35]; + static const uint16_t table1_158_inner_[18]; + static const uint8_t table1_159_emit_[68]; + static const uint8_t table1_160_emit_[16]; + static const uint8_t table1_161_emit_[28]; + static const uint8_t table1_162_emit_[35]; + static const uint16_t table1_162_inner_[18]; + static const uint8_t table1_163_emit_[68]; static const uint8_t table1_164_emit_[16]; - static const uint8_t table1_165_emit_[20]; - static const uint16_t table1_165_inner_[10]; - static const uint8_t table1_165_outer_[64]; - static const uint8_t table1_166_emit_[32]; - static const uint16_t table1_166_inner_[16]; - static const uint8_t table1_166_outer_[64]; - static const uint8_t table1_167_emit_[36]; - static const uint16_t table1_167_inner_[19]; - static const uint8_t table1_167_outer_[64]; - static const uint8_t table1_168_emit_[8]; - static const uint8_t table1_169_emit_[8]; - static const uint8_t table1_170_emit_[11]; - static const uint16_t table1_170_inner_[6]; - static const uint8_t table1_171_emit_[16]; + static const uint8_t table1_165_emit_[28]; + static const uint8_t table1_166_emit_[35]; + static const uint16_t table1_166_inner_[18]; + static const uint8_t table1_167_emit_[68]; + static const uint8_t table1_168_emit_[16]; + static const uint8_t table1_169_emit_[28]; + static const uint8_t table1_170_emit_[35]; + static const uint16_t table1_170_inner_[18]; + static const uint8_t table1_171_emit_[68]; static const uint8_t table1_172_emit_[16]; - static const uint8_t table1_173_emit_[20]; - static const uint8_t table1_174_emit_[32]; - static const uint8_t table1_175_emit_[36]; - static const uint8_t table1_176_emit_[8]; - static const uint8_t table1_177_emit_[8]; - static const uint8_t table1_178_emit_[11]; - static const uint16_t table1_178_inner_[6]; - static const uint8_t table1_179_emit_[16]; + static const uint8_t table1_173_emit_[28]; + static const uint8_t table1_174_emit_[35]; + static const uint16_t table1_174_inner_[18]; + static const uint8_t table1_175_emit_[68]; + static const uint8_t table1_176_emit_[16]; + static const uint8_t table1_177_emit_[28]; + static const uint8_t table1_178_emit_[35]; + static const uint16_t table1_178_inner_[18]; + static const uint8_t table1_179_emit_[68]; static const uint8_t table1_180_emit_[16]; - static const uint8_t table1_181_emit_[20]; - static const uint8_t table1_182_emit_[32]; - static const uint8_t table1_183_emit_[36]; - static const uint8_t table1_184_emit_[8]; - static const uint8_t table1_185_emit_[8]; - static const uint8_t table1_186_emit_[12]; - static const uint8_t table1_187_emit_[16]; - static const uint8_t table1_188_emit_[16]; - static const uint8_t table1_189_emit_[20]; - static const uint8_t table1_190_emit_[32]; - static const uint8_t table1_191_emit_[36]; - static const uint8_t table1_192_emit_[8]; - static const uint8_t table1_193_emit_[8]; - static const uint8_t table1_194_emit_[12]; - static const uint8_t table1_195_emit_[15]; - static const uint16_t table1_195_inner_[8]; - static const uint8_t table1_196_emit_[16]; - static const uint8_t table1_197_emit_[20]; - static const uint8_t table1_198_emit_[32]; - static const uint8_t table1_199_emit_[36]; - static const uint8_t table1_200_emit_[8]; - static const uint8_t table1_201_emit_[8]; - static const uint8_t table1_202_emit_[12]; - static const uint8_t table1_203_emit_[15]; - static const uint16_t table1_203_inner_[8]; - static const uint8_t table1_204_emit_[16]; - static const uint8_t table1_205_emit_[20]; - static const uint8_t table1_206_emit_[32]; - static const uint8_t table1_207_emit_[36]; - static const uint8_t table1_208_emit_[8]; - static const uint8_t table1_209_emit_[8]; - static const uint8_t table1_210_emit_[12]; - static const uint8_t table1_211_emit_[15]; - static const uint16_t table1_211_inner_[8]; - static const uint8_t table1_212_emit_[16]; - static const uint8_t table1_213_emit_[20]; - static const uint8_t table1_214_emit_[32]; - static const uint8_t table1_215_emit_[36]; - static const uint8_t table1_216_emit_[8]; - static const uint8_t table1_217_emit_[8]; - static const uint8_t table1_218_emit_[12]; - static const uint8_t table1_219_emit_[15]; - static const uint16_t table1_219_inner_[8]; - static const uint8_t table1_220_emit_[16]; - static const uint8_t table1_221_emit_[20]; - static const uint8_t table1_222_emit_[32]; - static const uint8_t table1_223_emit_[36]; - static const uint8_t table1_224_emit_[8]; - static const uint8_t table1_225_emit_[8]; - static const uint8_t table1_226_emit_[12]; - static const uint8_t table1_227_emit_[15]; - static const uint16_t table1_227_inner_[8]; - static const uint8_t table1_228_emit_[16]; - static const uint8_t table1_229_emit_[20]; - static const uint8_t table1_230_emit_[32]; - static const uint8_t table1_231_emit_[36]; - static const uint8_t table1_232_emit_[8]; - static const uint8_t table1_233_emit_[8]; - static const uint8_t table1_234_emit_[12]; - static const uint8_t table1_235_emit_[15]; - static const uint16_t table1_235_inner_[8]; - static const uint8_t table1_236_emit_[16]; - static const uint8_t table1_237_emit_[20]; - static const uint8_t table1_238_emit_[32]; - static const uint8_t table1_239_emit_[36]; - static const uint8_t table1_240_emit_[8]; - static const uint8_t table1_241_emit_[8]; - static const uint8_t table1_242_emit_[12]; - static const uint8_t table1_243_emit_[15]; - static const uint16_t table1_243_inner_[8]; - static const uint8_t table1_244_emit_[16]; - static const uint8_t table1_245_emit_[20]; - static const uint8_t table1_246_emit_[32]; - static const uint8_t table1_247_emit_[36]; - static const uint8_t table1_248_emit_[8]; - static const uint8_t table1_249_emit_[8]; - static const uint8_t table1_250_emit_[12]; - static const uint8_t table1_251_emit_[16]; - static const uint8_t table1_252_emit_[16]; - static const uint8_t table1_253_emit_[20]; - static const uint8_t table1_254_emit_[32]; - static const uint8_t table1_255_emit_[36]; - static const uint8_t table1_256_emit_[8]; - static const uint8_t table1_257_emit_[8]; - static const uint8_t table1_258_emit_[12]; - static const uint8_t table1_259_emit_[16]; - static const uint8_t table1_260_emit_[15]; - static const uint8_t table1_261_emit_[20]; - static const uint8_t table1_262_emit_[32]; - static const uint8_t table1_263_emit_[36]; - static const uint8_t table1_264_emit_[8]; - static const uint8_t table1_265_emit_[8]; - static const uint8_t table1_266_emit_[12]; - static const uint8_t table1_267_emit_[16]; - static const uint8_t table1_268_emit_[15]; - static const uint8_t table1_269_emit_[20]; - static const uint8_t table1_270_emit_[32]; - static const uint8_t table1_271_emit_[36]; - static const uint8_t table1_272_emit_[8]; - static const uint8_t table1_273_emit_[8]; - static const uint8_t table1_274_emit_[12]; - static const uint8_t table1_275_emit_[16]; - static const uint8_t table1_276_emit_[15]; - static const uint8_t table1_277_emit_[20]; - static const uint8_t table1_278_emit_[32]; - static const uint8_t table1_279_emit_[36]; - static const uint8_t table1_280_emit_[8]; - static const uint8_t table1_281_emit_[8]; - static const uint8_t table1_282_emit_[12]; - static const uint8_t table1_283_emit_[16]; - static const uint8_t table1_284_emit_[15]; - static const uint8_t table1_285_emit_[20]; - static const uint8_t table1_286_emit_[32]; - static const uint8_t table1_287_emit_[36]; - static const uint8_t table1_288_emit_[8]; - static const uint8_t table1_289_emit_[8]; - static const uint8_t table1_290_emit_[12]; - static const uint8_t table1_291_emit_[16]; - static const uint8_t table1_292_emit_[15]; - static const uint8_t table1_293_emit_[20]; - static const uint8_t table1_294_emit_[32]; - static const uint8_t table1_295_emit_[36]; - static const uint8_t table1_296_emit_[8]; - static const uint8_t table1_297_emit_[8]; - static const uint8_t table1_298_emit_[12]; - static const uint8_t table1_299_emit_[16]; - static const uint8_t table1_300_emit_[15]; - static const uint8_t table1_301_emit_[20]; - static const uint8_t table1_302_emit_[32]; - static const uint8_t table1_303_emit_[36]; - static const uint8_t table1_304_emit_[8]; - static const uint8_t table1_305_emit_[8]; - static const uint8_t table1_306_emit_[12]; - static const uint8_t table1_307_emit_[16]; - static const uint8_t table1_308_emit_[15]; - static const uint8_t table1_309_emit_[20]; - static const uint8_t table1_310_emit_[32]; - static const uint8_t table1_311_emit_[36]; - static const uint8_t table1_312_emit_[8]; - static const uint8_t table1_313_emit_[8]; - static const uint8_t table1_314_emit_[12]; - static const uint8_t table1_315_emit_[16]; - static const uint8_t table1_316_emit_[16]; - static const uint8_t table1_317_emit_[20]; - static const uint8_t table1_318_emit_[32]; - static const uint8_t table1_319_emit_[36]; - static const uint8_t table1_320_emit_[8]; - static const uint8_t table1_321_emit_[8]; - static const uint8_t table1_322_emit_[12]; - static const uint8_t table1_323_emit_[16]; - static const uint8_t table1_324_emit_[16]; - static const uint8_t table1_325_emit_[19]; - static const uint16_t table1_325_inner_[10]; - static const uint8_t table1_326_emit_[32]; - static const uint8_t table1_327_emit_[36]; - static const uint8_t table1_328_emit_[8]; - static const uint8_t table1_329_emit_[8]; - static const uint8_t table1_330_emit_[12]; - static const uint8_t table1_331_emit_[16]; - static const uint8_t table1_332_emit_[16]; - static const uint8_t table1_333_emit_[19]; - static const uint16_t table1_333_inner_[10]; - static const uint8_t table1_334_emit_[32]; - static const uint8_t table1_335_emit_[36]; - static const uint8_t table1_336_emit_[8]; - static const uint8_t table1_337_emit_[8]; - static const uint8_t table1_338_emit_[12]; - static const uint8_t table1_339_emit_[16]; - static const uint8_t table1_340_emit_[16]; - static const uint8_t table1_341_emit_[19]; - static const uint16_t table1_341_inner_[10]; - static const uint8_t table1_342_emit_[32]; - static const uint8_t table1_343_emit_[36]; - static const uint8_t table1_344_emit_[8]; - static const uint8_t table1_345_emit_[8]; - static const uint8_t table1_346_emit_[12]; - static const uint8_t table1_347_emit_[16]; - static const uint8_t table1_348_emit_[16]; - static const uint8_t table1_349_emit_[19]; - static const uint16_t table1_349_inner_[10]; - static const uint8_t table1_350_emit_[32]; - static const uint8_t table1_351_emit_[36]; - static const uint8_t table1_352_emit_[8]; - static const uint8_t table1_353_emit_[8]; - static const uint8_t table1_354_emit_[12]; - static const uint8_t table1_355_emit_[16]; - static const uint8_t table1_356_emit_[16]; - static const uint8_t table1_357_emit_[19]; - static const uint16_t table1_357_inner_[10]; - static const uint8_t table1_358_emit_[32]; - static const uint8_t table1_359_emit_[36]; - static const uint8_t table1_360_emit_[8]; - static const uint8_t table1_361_emit_[8]; - static const uint8_t table1_362_emit_[12]; - static const uint8_t table1_363_emit_[16]; - static const uint8_t table1_364_emit_[16]; - static const uint8_t table1_365_emit_[19]; - static const uint16_t table1_365_inner_[10]; - static const uint8_t table1_366_emit_[32]; - static const uint8_t table1_367_emit_[36]; - static const uint8_t table1_368_emit_[16]; - static const uint8_t table1_369_emit_[28]; - static const uint16_t table1_369_inner_[14]; - static const uint8_t table1_369_outer_[64]; - static const uint8_t table1_370_emit_[35]; - static const uint16_t table1_370_inner_[18]; - static const uint8_t table1_370_outer_[64]; - static const uint8_t table1_371_emit_[68]; - static const uint16_t table1_371_inner_[35]; - static const uint8_t table1_371_outer_[64]; - static const uint8_t table1_372_emit_[16]; - static const uint8_t table1_373_emit_[28]; - static const uint8_t table1_374_emit_[35]; - static const uint16_t table1_374_inner_[18]; - static const uint8_t table1_375_emit_[68]; - static const uint8_t table1_376_emit_[16]; - static const uint8_t table1_377_emit_[28]; - static const uint8_t table1_378_emit_[35]; - static const uint16_t table1_378_inner_[18]; - static const uint8_t table1_379_emit_[68]; - static const uint8_t table1_380_emit_[16]; - static const uint8_t table1_381_emit_[28]; - static const uint8_t table1_382_emit_[36]; - static const uint16_t table1_382_inner_[18]; - static const uint8_t table1_383_emit_[68]; - static const uint8_t table1_384_emit_[16]; - static const uint8_t table1_385_emit_[28]; - static const uint8_t table1_386_emit_[36]; - static const uint8_t table1_387_emit_[67]; - static const uint16_t table1_387_inner_[35]; - static const uint8_t table1_388_emit_[16]; - static const uint8_t table1_389_emit_[28]; - static const uint8_t table1_390_emit_[36]; - static const uint8_t table1_391_emit_[67]; - static const uint16_t table1_391_inner_[35]; - static const uint8_t table1_392_emit_[16]; - static const uint8_t table1_393_emit_[28]; - static const uint8_t table1_394_emit_[36]; - static const uint8_t table1_395_emit_[67]; - static const uint16_t table1_395_inner_[35]; - static const uint8_t table1_396_emit_[16]; - static const uint8_t table1_397_emit_[28]; - static const uint8_t table1_398_emit_[36]; - static const uint8_t table1_399_emit_[67]; - static const uint16_t table1_399_inner_[35]; - static const uint8_t table1_400_emit_[16]; - static const uint8_t table1_401_emit_[28]; - static const uint8_t table1_402_emit_[36]; - static const uint8_t table1_403_emit_[67]; - static const uint16_t table1_403_inner_[35]; - static const uint8_t table1_404_emit_[16]; - static const uint8_t table1_405_emit_[28]; - static const uint8_t table1_406_emit_[36]; - static const uint8_t table1_407_emit_[67]; - static const uint16_t table1_407_inner_[35]; - static const uint8_t table1_408_emit_[16]; - static const uint8_t table1_409_emit_[28]; - static const uint8_t table1_410_emit_[36]; - static const uint8_t table1_411_emit_[67]; - static const uint16_t table1_411_inner_[35]; - static const uint8_t table1_412_emit_[16]; - static const uint8_t table1_413_emit_[28]; - static const uint8_t table1_414_emit_[36]; - static const uint8_t table1_415_emit_[67]; - static const uint16_t table1_415_inner_[35]; - static const uint8_t table1_416_emit_[16]; - static const uint8_t table1_417_emit_[28]; - static const uint8_t table1_418_emit_[36]; - static const uint8_t table1_419_emit_[67]; - static const uint16_t table1_419_inner_[35]; - static const uint8_t table1_420_emit_[16]; - static const uint8_t table1_421_emit_[28]; - static const uint8_t table1_422_emit_[36]; - static const uint8_t table1_423_emit_[67]; - static const uint16_t table1_423_inner_[35]; - static const uint8_t table1_424_emit_[16]; - static const uint8_t table1_425_emit_[28]; - static const uint8_t table1_426_emit_[36]; - static const uint8_t table1_427_emit_[67]; - static const uint16_t table1_427_inner_[35]; - static const uint8_t table1_428_emit_[16]; - static const uint8_t table1_429_emit_[28]; - static const uint8_t table1_430_emit_[36]; - static const uint8_t table1_431_emit_[67]; - static const uint16_t table1_431_inner_[35]; - static const uint8_t table1_432_emit_[16]; - static const uint8_t table1_433_emit_[28]; - static const uint8_t table1_434_emit_[36]; - static const uint8_t table1_435_emit_[67]; - static const uint16_t table1_435_inner_[35]; - static const uint8_t table1_436_emit_[16]; - static const uint8_t table1_437_emit_[28]; - static const uint8_t table1_438_emit_[36]; - static const uint8_t table1_439_emit_[67]; - static const uint16_t table1_439_inner_[35]; - static const uint8_t table1_440_emit_[16]; - static const uint8_t table1_441_emit_[28]; - static const uint8_t table1_442_emit_[36]; - static const uint8_t table1_443_emit_[67]; - static const uint16_t table1_443_inner_[35]; - static const uint8_t table1_444_emit_[16]; - static const uint8_t table1_445_emit_[28]; - static const uint8_t table1_446_emit_[36]; - static const uint8_t table1_447_emit_[67]; - static const uint16_t table1_447_inner_[35]; - static const uint8_t table1_448_emit_[16]; - static const uint8_t table1_449_emit_[28]; - static const uint8_t table1_450_emit_[36]; - static const uint8_t table1_451_emit_[67]; - static const uint16_t table1_451_inner_[35]; - static const uint8_t table1_452_emit_[16]; - static const uint8_t table1_453_emit_[28]; - static const uint8_t table1_454_emit_[36]; - static const uint8_t table1_455_emit_[67]; - static const uint16_t table1_455_inner_[35]; - static const uint8_t table1_456_emit_[16]; - static const uint8_t table1_457_emit_[28]; - static const uint8_t table1_458_emit_[36]; - static const uint8_t table1_459_emit_[67]; - static const uint16_t table1_459_inner_[35]; - static const uint8_t table1_460_emit_[16]; - static const uint8_t table1_461_emit_[28]; - static const uint8_t table1_462_emit_[36]; - static const uint8_t table1_463_emit_[67]; - static const uint16_t table1_463_inner_[35]; - static const uint8_t table1_464_emit_[16]; - static const uint8_t table1_465_emit_[28]; - static const uint8_t table1_466_emit_[36]; - static const uint8_t table1_467_emit_[67]; - static const uint16_t table1_467_inner_[35]; - static const uint8_t table1_468_emit_[16]; - static const uint8_t table1_469_emit_[28]; - static const uint8_t table1_470_emit_[36]; - static const uint8_t table1_471_emit_[67]; - static const uint16_t table1_471_inner_[35]; - static const uint8_t table1_472_emit_[16]; - static const uint8_t table1_473_emit_[28]; - static const uint8_t table1_474_emit_[36]; - static const uint8_t table1_475_emit_[67]; - static const uint16_t table1_475_inner_[35]; - static const uint8_t table1_476_emit_[16]; - static const uint8_t table1_477_emit_[28]; - static const uint8_t table1_478_emit_[36]; - static const uint8_t table1_479_emit_[67]; - static const uint16_t table1_479_inner_[35]; - static const uint8_t table1_480_emit_[16]; - static const uint8_t table1_481_emit_[28]; - static const uint8_t table1_482_emit_[36]; - static const uint8_t table1_483_emit_[67]; - static const uint16_t table1_483_inner_[35]; - static const uint8_t table1_484_emit_[16]; - static const uint8_t table1_485_emit_[28]; - static const uint8_t table1_486_emit_[36]; - static const uint8_t table1_487_emit_[67]; - static const uint16_t table1_487_inner_[35]; - static const uint8_t table1_488_emit_[16]; - static const uint8_t table1_489_emit_[28]; - static const uint8_t table1_490_emit_[36]; - static const uint8_t table1_491_emit_[67]; - static const uint16_t table1_491_inner_[35]; - static const uint8_t table1_492_emit_[16]; - static const uint8_t table1_493_emit_[28]; - static const uint8_t table1_494_emit_[36]; - static const uint8_t table1_495_emit_[67]; - static const uint16_t table1_495_inner_[35]; - static const uint8_t table1_496_emit_[44]; - static const uint16_t table1_496_inner_[22]; - static const uint8_t table1_496_outer_[64]; - static const uint8_t table1_497_emit_[92]; - static const uint16_t table1_497_inner_[47]; - static const uint8_t table1_497_outer_[64]; - static const uint8_t table1_498_emit_[44]; - static const uint8_t table1_499_emit_[92]; - static const uint8_t table1_500_emit_[44]; - static const uint8_t table1_501_emit_[92]; - static const uint8_t table1_502_emit_[44]; - static const uint8_t table1_503_emit_[92]; - static const uint8_t table1_504_emit_[44]; - static const uint8_t table1_505_emit_[92]; - static const uint8_t table1_506_emit_[44]; - static const uint8_t table1_507_emit_[92]; - static const uint8_t table1_508_emit_[40]; - static const uint16_t table1_508_inner_[22]; - static const uint8_t table1_509_emit_[40]; - static const uint8_t table1_510_emit_[22]; - static const uint16_t table1_510_inner_[13]; - static const uint8_t table1_510_outer_[64]; - static const uint8_t table1_511_emit_[14]; - static const uint16_t table1_511_inner_[15]; - static const uint8_t table1_511_outer_[64]; - static const uint8_t* const table1_emit_[512]; - static const uint16_t* const table1_inner_[512]; - static const uint8_t* const table1_outer_[512]; - static const uint8_t table13_0_inner_[5]; - static const uint8_t table14_0_emit_[11]; - static const uint8_t table14_0_ops_[32]; - static const uint8_t table15_0_emit_[24]; - static const uint8_t table15_0_ops_[64]; - static const uint8_t table12_0_emit_[50]; - static const uint16_t table12_0_inner_[70]; - static const uint8_t table12_0_outer_[128]; - static const uint8_t table33_0_emit_[15]; - static const uint8_t table33_0_inner_[16]; - static const uint8_t table32_0_emit_[17]; - static const uint8_t table32_0_ops_[32]; - static const uint8_t table36_0_emit_[6]; - static const uint8_t table36_0_inner_[6]; - static const uint8_t table39_0_emit_[17]; - static const uint8_t table39_0_ops_[32]; - static const uint8_t table40_0_emit_[46]; - static const uint8_t table40_0_ops_[64]; - static const uint8_t table41_0_ops_[128]; - static const uint8_t table38_0_emit_[4]; - static const uint16_t table38_0_ops_[32]; - static const uint8_t table38_1_emit_[4]; - static const uint8_t table38_2_emit_[4]; - static const uint8_t table38_3_emit_[4]; - static const uint8_t table38_4_emit_[7]; - static const uint16_t table38_4_ops_[32]; - static const uint8_t table38_5_emit_[8]; - static const uint16_t table38_5_ops_[32]; - static const uint8_t table38_6_emit_[8]; - static const uint8_t table38_7_emit_[10]; - static const uint16_t table38_7_ops_[32]; - static const uint8_t* const table38_emit_[8]; - static const uint16_t* const table38_ops_[8]; + static const uint8_t table1_181_emit_[28]; + static const uint8_t table1_182_emit_[35]; + static const uint16_t table1_182_inner_[18]; + static const uint8_t table1_183_emit_[68]; + static const uint8_t table1_184_emit_[44]; + static const uint16_t table1_184_inner_[22]; + static const uint8_t table1_184_outer_[64]; + static const uint8_t table1_185_emit_[91]; + static const uint16_t table1_185_inner_[47]; + static const uint8_t table1_185_outer_[64]; + static const uint8_t table1_186_emit_[44]; + static const uint8_t table1_187_emit_[91]; + static const uint16_t table1_187_inner_[47]; + static const uint8_t table1_188_emit_[44]; + static const uint8_t table1_189_emit_[91]; + static const uint16_t table1_189_inner_[47]; + static const uint8_t table1_190_emit_[44]; + static const uint8_t table1_191_emit_[91]; + static const uint16_t table1_191_inner_[47]; + static const uint8_t table1_192_emit_[44]; + static const uint8_t table1_193_emit_[91]; + static const uint16_t table1_193_inner_[47]; + static const uint8_t table1_194_emit_[44]; + static const uint8_t table1_195_emit_[91]; + static const uint16_t table1_195_inner_[47]; + static const uint8_t table1_196_emit_[44]; + static const uint8_t table1_197_emit_[91]; + static const uint16_t table1_197_inner_[47]; + static const uint8_t table1_198_emit_[44]; + static const uint8_t table1_199_emit_[91]; + static const uint16_t table1_199_inner_[47]; + static const uint8_t table1_200_emit_[44]; + static const uint8_t table1_201_emit_[91]; + static const uint16_t table1_201_inner_[47]; + static const uint8_t table1_202_emit_[44]; + static const uint8_t table1_203_emit_[91]; + static const uint16_t table1_203_inner_[47]; + static const uint8_t table1_204_emit_[44]; + static const uint8_t table1_205_emit_[91]; + static const uint16_t table1_205_inner_[47]; + static const uint8_t table1_206_emit_[44]; + static const uint8_t table1_207_emit_[91]; + static const uint16_t table1_207_inner_[47]; + static const uint8_t table1_208_emit_[44]; + static const uint8_t table1_209_emit_[91]; + static const uint16_t table1_209_inner_[47]; + static const uint8_t table1_210_emit_[44]; + static const uint8_t table1_211_emit_[91]; + static const uint16_t table1_211_inner_[47]; + static const uint8_t table1_212_emit_[44]; + static const uint8_t table1_213_emit_[91]; + static const uint16_t table1_213_inner_[47]; + static const uint8_t table1_214_emit_[44]; + static const uint8_t table1_215_emit_[91]; + static const uint16_t table1_215_inner_[47]; + static const uint8_t table1_216_emit_[44]; + static const uint8_t table1_217_emit_[91]; + static const uint16_t table1_217_inner_[47]; + static const uint8_t table1_218_emit_[44]; + static const uint8_t table1_219_emit_[91]; + static const uint16_t table1_219_inner_[47]; + static const uint8_t table1_220_emit_[44]; + static const uint8_t table1_221_emit_[91]; + static const uint16_t table1_221_inner_[47]; + static const uint8_t table1_222_emit_[44]; + static const uint8_t table1_223_emit_[91]; + static const uint16_t table1_223_inner_[47]; + static const uint8_t table1_224_emit_[44]; + static const uint8_t table1_225_emit_[91]; + static const uint16_t table1_225_inner_[47]; + static const uint8_t table1_226_emit_[44]; + static const uint8_t table1_227_emit_[91]; + static const uint16_t table1_227_inner_[47]; + static const uint8_t table1_228_emit_[44]; + static const uint8_t table1_229_emit_[91]; + static const uint16_t table1_229_inner_[47]; + static const uint8_t table1_230_emit_[44]; + static const uint8_t table1_231_emit_[91]; + static const uint16_t table1_231_inner_[47]; + static const uint8_t table1_232_emit_[44]; + static const uint8_t table1_233_emit_[91]; + static const uint16_t table1_233_inner_[47]; + static const uint8_t table1_234_emit_[44]; + static const uint8_t table1_235_emit_[91]; + static const uint16_t table1_235_inner_[47]; + static const uint8_t table1_236_emit_[44]; + static const uint8_t table1_237_emit_[91]; + static const uint16_t table1_237_inner_[47]; + static const uint8_t table1_238_emit_[44]; + static const uint8_t table1_239_emit_[91]; + static const uint16_t table1_239_inner_[47]; + static const uint8_t table1_240_emit_[44]; + static const uint8_t table1_241_emit_[91]; + static const uint16_t table1_241_inner_[47]; + static const uint8_t table1_242_emit_[44]; + static const uint8_t table1_243_emit_[91]; + static const uint16_t table1_243_inner_[47]; + static const uint8_t table1_244_emit_[44]; + static const uint8_t table1_245_emit_[91]; + static const uint16_t table1_245_inner_[47]; + static const uint8_t table1_246_emit_[44]; + static const uint8_t table1_247_emit_[92]; + static const uint16_t table1_247_inner_[47]; + static const uint8_t table1_248_emit_[72]; + static const uint16_t table1_248_inner_[37]; + static const uint8_t table1_248_outer_[64]; + static const uint8_t table1_249_emit_[72]; + static const uint8_t table1_250_emit_[72]; + static const uint8_t table1_251_emit_[72]; + static const uint8_t table1_252_emit_[72]; + static const uint8_t table1_253_emit_[72]; + static const uint8_t table1_254_emit_[4]; + static const uint16_t table1_254_inner_[4]; + static const uint8_t table1_255_emit_[14]; + static const uint16_t table1_255_inner_[16]; + static const uint8_t table1_255_outer_[64]; + static const uint8_t* const table1_emit_[256]; + static const uint16_t* const table1_inner_[256]; + static const uint8_t* const table1_outer_[256]; + static const uint8_t table15_0_outer_[8]; + static const uint8_t table16_0_outer_[16]; + static const uint16_t table12_0_inner_[17]; + static const uint8_t table24_0_emit_[8]; + static const uint8_t table24_0_inner_[8]; + static const uint8_t table25_0_emit_[8]; + static const uint8_t table26_0_emit_[16]; + static const uint8_t table26_0_inner_[16]; + static const uint8_t table27_0_emit_[7]; + static const uint8_t table27_0_inner_[7]; + static const uint8_t table30_0_inner_[5]; + static const uint8_t table29_0_emit_[12]; + static const uint8_t table29_0_inner_[12]; + static const uint8_t table32_0_emit_[5]; + static const uint8_t table32_0_inner_[7]; + static const uint8_t table33_0_emit_[17]; + static const uint8_t table33_0_ops_[32]; + static const uint8_t table34_0_emit_[21]; + static const uint8_t table34_0_ops_[64]; + static const uint8_t table35_0_emit_[36]; + static const uint8_t table35_0_ops_[128]; + static const uint8_t table36_0_emit_[55]; + static const uint8_t table36_0_ops_[256]; + static const uint8_t table37_0_emit_[40]; + static const uint8_t table37_0_ops_[64]; + static const uint8_t table37_1_emit_[40]; + static const uint8_t table37_2_emit_[22]; + static const uint8_t table37_2_ops_[64]; + static const uint8_t table37_3_emit_[4]; + static const uint8_t table37_4_emit_[4]; + static const uint8_t table37_5_emit_[6]; + static const uint8_t table37_6_emit_[17]; + static const uint8_t table37_6_ops_[64]; + static const uint8_t table37_7_emit_[46]; + static const uint8_t table37_7_ops_[64]; + static const uint8_t* const table37_emit_[8]; + static const uint8_t* const table37_ops_[8]; + static const uint8_t table38_0_emit_[72]; + static const uint16_t table38_0_ops_[64]; + static const uint8_t table38_1_emit_[72]; + static const uint8_t table38_2_emit_[72]; + static const uint8_t table38_3_emit_[72]; + static const uint8_t table38_4_emit_[72]; + static const uint8_t table38_5_emit_[40]; + static const uint16_t table38_5_ops_[64]; + static const uint8_t table38_6_emit_[40]; + static const uint8_t table38_7_emit_[40]; + static const uint8_t table38_8_emit_[40]; + static const uint8_t table38_9_emit_[40]; + static const uint8_t table38_10_emit_[40]; + static const uint8_t table38_11_emit_[4]; + static const uint16_t table38_11_ops_[64]; + static const uint8_t table38_12_emit_[8]; + static const uint16_t table38_12_ops_[64]; + static const uint8_t table38_13_emit_[9]; + static const uint16_t table38_13_ops_[64]; + static const uint8_t table38_14_emit_[16]; + static const uint16_t table38_14_ops_[64]; + static const uint8_t table38_15_emit_[30]; + static const uint16_t table38_15_ops_[64]; + static const uint8_t* const table38_emit_[16]; + static const uint16_t* const table38_ops_[16]; + static const uint8_t table31_0_emit_[1]; + static const uint16_t table31_0_ops_[64]; + static const uint8_t table31_2_emit_[1]; + static const uint8_t table31_4_emit_[1]; + static const uint8_t table31_6_emit_[1]; + static const uint8_t table31_8_emit_[1]; + static const uint8_t table31_10_emit_[1]; + static const uint16_t table31_10_ops_[64]; + static const uint8_t table31_11_emit_[1]; + static const uint8_t table31_12_emit_[1]; + static const uint8_t table31_13_emit_[1]; + static const uint8_t table31_14_emit_[1]; + static const uint8_t table31_15_emit_[1]; + static const uint8_t table31_16_emit_[1]; + static const uint8_t table31_17_emit_[1]; + static const uint8_t table31_18_emit_[1]; + static const uint8_t table31_19_emit_[1]; + static const uint8_t table31_20_emit_[1]; + static const uint8_t table31_21_emit_[1]; + static const uint8_t table31_22_emit_[2]; + static const uint16_t table31_22_ops_[64]; + static const uint8_t table31_23_emit_[2]; + static const uint8_t table31_24_emit_[4]; + static const uint16_t table31_24_ops_[64]; + static const uint8_t table31_25_emit_[4]; + static const uint8_t table31_26_emit_[4]; + static const uint8_t table31_27_emit_[5]; + static const uint16_t table31_27_ops_[64]; + static const uint8_t table31_28_emit_[8]; + static const uint16_t table31_28_ops_[64]; + static const uint8_t table31_29_emit_[8]; + static const uint8_t table31_30_emit_[15]; + static const uint16_t table31_30_ops_[64]; + static const uint8_t table31_31_emit_[18]; + static const uint16_t table31_31_ops_[64]; + static const uint8_t* const table31_emit_[32]; + static const uint16_t* const table31_ops_[32]; }; template class HuffDecoder : public HuffDecoderCommon { @@ -1599,11 +1178,11 @@ class HuffDecoder : public HuffDecoderCommon { : sink_(sink), begin_(begin), end_(end) {} bool Run() { while (!done_) { - if (!RefillTo15()) { + if (!RefillTo14()) { Done0(); break; } - const auto index = (buffer_ >> (buffer_len_ - 15)) & 0x7fff; + const auto index = (buffer_ >> (buffer_len_ - 14)) & 0x3fff; const auto op = GetOp1(index); const int consumed = op & 15; buffer_len_ -= consumed; @@ -1612,20 +1191,18 @@ class HuffDecoder : public HuffDecoderCommon { case 0: { sink_(GetEmit1(index, emit_ofs + 0)); sink_(GetEmit1(index, emit_ofs + 1)); - sink_(GetEmit1(index, emit_ofs + 2)); break; } case 1: { sink_(GetEmit1(index, emit_ofs + 0)); - sink_(GetEmit1(index, emit_ofs + 1)); break; } case 2: { - sink_(GetEmit1(index, emit_ofs + 0)); + DecodeStep0(); break; } case 3: { - DecodeStep0(); + DecodeStep1(); break; } } @@ -1634,7 +1211,7 @@ class HuffDecoder : public HuffDecoderCommon { } private: - bool RefillTo15() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool RefillTo14() { switch (buffer_len_) { case 0: { return Read2to8Bytes(); @@ -1643,10 +1220,10 @@ class HuffDecoder : public HuffDecoderCommon { case 2: case 3: case 4: - case 5: - case 6: { + case 5: { return Read2to7Bytes(); } + case 6: case 7: case 8: { return Read1to7Bytes(); @@ -1655,14 +1232,13 @@ class HuffDecoder : public HuffDecoderCommon { case 10: case 11: case 12: - case 13: - case 14: { + case 13: { return Read1to6Bytes(); } } return true; } - bool Read2to8Bytes() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool Read2to8Bytes() { switch (end_ - begin_) { case 0: case 1: { @@ -1698,20 +1274,20 @@ class HuffDecoder : public HuffDecoderCommon { } } } - void Fill2() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill2() { buffer_ = (buffer_ << 16) | (static_cast(begin_[0]) << 8) | (static_cast(begin_[1]) << 0); begin_ += 2; buffer_len_ += 16; } - void Fill3() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill3() { buffer_ = (buffer_ << 24) | (static_cast(begin_[0]) << 16) | (static_cast(begin_[1]) << 8) | (static_cast(begin_[2]) << 0); begin_ += 3; buffer_len_ += 24; } - void Fill4() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill4() { buffer_ = (buffer_ << 32) | (static_cast(begin_[0]) << 24) | (static_cast(begin_[1]) << 16) | (static_cast(begin_[2]) << 8) | @@ -1719,7 +1295,7 @@ class HuffDecoder : public HuffDecoderCommon { begin_ += 4; buffer_len_ += 32; } - void Fill5() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill5() { buffer_ = (buffer_ << 40) | (static_cast(begin_[0]) << 32) | (static_cast(begin_[1]) << 24) | (static_cast(begin_[2]) << 16) | @@ -1728,7 +1304,7 @@ class HuffDecoder : public HuffDecoderCommon { begin_ += 5; buffer_len_ += 40; } - void Fill6() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill6() { buffer_ = (buffer_ << 48) | (static_cast(begin_[0]) << 40) | (static_cast(begin_[1]) << 32) | (static_cast(begin_[2]) << 24) | @@ -1738,7 +1314,7 @@ class HuffDecoder : public HuffDecoderCommon { begin_ += 6; buffer_len_ += 48; } - void Fill7() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill7() { buffer_ = (buffer_ << 56) | (static_cast(begin_[0]) << 48) | (static_cast(begin_[1]) << 40) | (static_cast(begin_[2]) << 32) | @@ -1749,7 +1325,7 @@ class HuffDecoder : public HuffDecoderCommon { begin_ += 7; buffer_len_ += 56; } - void Fill8() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill8() { buffer_ = 0 | (static_cast(begin_[0]) << 56) | (static_cast(begin_[1]) << 48) | (static_cast(begin_[2]) << 40) | @@ -1761,7 +1337,7 @@ class HuffDecoder : public HuffDecoderCommon { begin_ += 8; buffer_len_ += 64; } - bool Read2to7Bytes() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool Read2to7Bytes() { switch (end_ - begin_) { case 0: case 1: { @@ -1793,7 +1369,7 @@ class HuffDecoder : public HuffDecoderCommon { } } } - bool Read1to7Bytes() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool Read1to7Bytes() { switch (end_ - begin_) { case 0: { return false; @@ -1828,12 +1404,12 @@ class HuffDecoder : public HuffDecoderCommon { } } } - void Fill1() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Fill1() { buffer_ = (buffer_ << 8) | (static_cast(begin_[0]) << 0); begin_ += 1; buffer_len_ += 8; } - bool Read1to6Bytes() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool Read1to6Bytes() { switch (end_ - begin_) { case 0: { return false; @@ -1864,7 +1440,7 @@ class HuffDecoder : public HuffDecoderCommon { } } } - void Done0() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done0() { done_ = true; switch (end_ - begin_) { case 1: { @@ -2035,76 +1611,119 @@ class HuffDecoder : public HuffDecoderCommon { } return; } - case 14: { - const auto index = buffer_ & 16383; - const auto op = GetOp11(index); - switch (op & 3) { - case 0: { - ok_ = false; - break; - } - case 1: { - sink_(GetEmit11(index, (op >> 2) + 0)); - sink_(GetEmit11(index, (op >> 2) + 1)); - break; - } - case 2: { - sink_(GetEmit11(index, (op >> 2) + 0)); - break; - } - } - return; - } case 0: { return; } } } - void DecodeStep0() { - if (!RefillTo7()) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep0() { + if (!RefillTo1()) { Done1(); return; } - const auto index = (buffer_ >> (buffer_len_ - 7)) & 0x7f; + const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; + const auto op = GetOp11(index); + const int consumed = op & 1; + buffer_len_ -= consumed; + const auto emit_ofs = op >> 1; + sink_(GetEmit11(index, emit_ofs + 0)); + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool RefillTo1() { + switch (buffer_len_) { + case 0: { + return Read1to8Bytes(); + } + } + return true; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool Read1to8Bytes() { + switch (end_ - begin_) { + case 0: { + return false; + } + case 1: { + Fill1(); + return true; + } + case 2: { + Fill2(); + return true; + } + case 3: { + Fill3(); + return true; + } + case 4: { + Fill4(); + return true; + } + case 5: { + Fill5(); + return true; + } + case 6: { + Fill6(); + return true; + } + case 7: { + Fill7(); + return true; + } + default: { + Fill8(); + return true; + } + } + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done1() { + done_ = true; + ok_ = false; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep1() { + if (!RefillTo5()) { + Done2(); + return; + } + const auto index = (buffer_ >> (buffer_len_ - 5)) & 0x1f; const auto op = GetOp12(index); const int consumed = op & 7; buffer_len_ -= consumed; - const auto emit_ofs = op >> 8; - switch ((op >> 3) & 31) { + const auto emit_ofs = op >> 7; + switch ((op >> 3) & 15) { case 0: { sink_(GetEmit12(index, emit_ofs + 0)); break; } case 1: { - DecodeStep1(); + DecodeStep2(); break; } case 2: { - DecodeStep2(); + DecodeStep3(); break; } case 3: { - DecodeStep3(); + DecodeStep4(); break; } case 4: { - DecodeStep4(); + DecodeStep5(); break; } case 5: { - DecodeStep5(); + DecodeStep6(); break; } case 6: { - DecodeStep6(); + DecodeStep7(); break; } case 7: { - DecodeStep7(); + DecodeStep8(); break; } case 8: { - DecodeStep8(); + DecodeStep12(); break; } case 9: { @@ -2116,48 +1735,20 @@ class HuffDecoder : public HuffDecoderCommon { break; } case 11: { - DecodeStep11(); + DecodeStep13(); break; } case 12: { - DecodeStep12(); + DecodeStep11(); break; } case 13: { - DecodeStep13(); - break; - } - case 14: { DecodeStep14(); break; } - case 15: { - DecodeStep18(); - break; - } - case 16: { - DecodeStep15(); - break; - } - case 17: { - DecodeStep16(); - break; - } - case 18: { - DecodeStep19(); - break; - } - case 19: { - DecodeStep17(); - break; - } - case 20: { - DecodeStep20(); - break; - } } } - bool RefillTo7() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool RefillTo5() { switch (buffer_len_) { case 0: { return Read1to8Bytes(); @@ -2165,102 +1756,66 @@ class HuffDecoder : public HuffDecoderCommon { case 1: case 2: case 3: - case 4: - case 5: - case 6: { + case 4: { return Read1to7Bytes(); } } return true; } - bool Read1to8Bytes() { - switch (end_ - begin_) { - case 0: { - return false; - } - case 1: { - Fill1(); - return true; - } - case 2: { - Fill2(); - return true; - } - case 3: { - Fill3(); - return true; - } - case 4: { - Fill4(); - return true; - } - case 5: { - Fill5(); - return true; - } - case 6: { - Fill6(); - return true; - } - case 7: { - Fill7(); - return true; - } - default: { - Fill8(); - return true; - } - } - } - void Done1() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done2() { done_ = true; switch (buffer_len_) { - case 1: - case 2: - case 3: { - ok_ = (buffer_ & ((1 << buffer_len_) - 1)) == (1 << buffer_len_) - 1; + case 1: { + const auto index = buffer_ & 1; + const auto op = GetOp13(index); + switch (op & 1) { + case 0: { + sink_(GetEmit13(index, (op >> 1) + 0)); + break; + } + } return; } - case 4: { - const auto index = buffer_ & 15; - const auto op = GetOp13(index); + case 2: { + const auto index = buffer_ & 3; + const auto op = GetOp14(index); switch (op & 3) { case 0: { - sink_(GetEmit13(index, (op >> 2) + 0)); + ok_ = false; break; } case 1: { - ok_ = false; + sink_(GetEmit14(index, (op >> 2) + 0)); break; } } return; } - case 5: { - const auto index = buffer_ & 31; - const auto op = GetOp14(index); + case 3: { + const auto index = buffer_ & 7; + const auto op = GetOp15(index); switch (op & 3) { case 0: { ok_ = false; break; } case 1: { - sink_(GetEmit14(index, (op >> 2) + 0)); + sink_(GetEmit15(index, (op >> 2) + 0)); break; } } return; } - case 6: { - const auto index = buffer_ & 63; - const auto op = GetOp15(index); + case 4: { + const auto index = buffer_ & 15; + const auto op = GetOp16(index); switch (op & 3) { case 0: { ok_ = false; break; } case 1: { - sink_(GetEmit15(index, (op >> 2) + 0)); + sink_(GetEmit16(index, (op >> 2) + 0)); break; } } @@ -2271,63 +1826,39 @@ class HuffDecoder : public HuffDecoderCommon { } } } - void DecodeStep1() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep2() { if (!RefillTo1()) { - Done2(); + Done3(); return; } const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp16(index); + const auto op = GetOp17(index); const int consumed = op & 1; buffer_len_ -= consumed; const auto emit_ofs = op >> 1; - sink_(GetEmit16(index, emit_ofs + 0)); - } - bool RefillTo1() { - switch (buffer_len_) { - case 0: { - return Read1to8Bytes(); - } - } - return true; + sink_(GetEmit17(index, emit_ofs + 0)); } - void Done2() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done3() { done_ = true; ok_ = false; } - void DecodeStep2() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep3() { if (!RefillTo1()) { - Done3(); + Done4(); return; } const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp17(index); + const auto op = GetOp18(index); const int consumed = op & 1; buffer_len_ -= consumed; const auto emit_ofs = op >> 1; - sink_(GetEmit17(index, emit_ofs + 0)); + sink_(GetEmit18(index, emit_ofs + 0)); } - void Done3() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done4() { done_ = true; ok_ = false; } - void DecodeStep3() { - if (!RefillTo1()) { - Done4(); - return; - } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp18(index); - const int consumed = op & 1; - buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; - sink_(GetEmit18(index, emit_ofs + 0)); - } - void Done4() { - done_ = true; - ok_ = false; - } - void DecodeStep4() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep4() { if (!RefillTo1()) { Done5(); return; @@ -2339,11 +1870,11 @@ class HuffDecoder : public HuffDecoderCommon { const auto emit_ofs = op >> 1; sink_(GetEmit19(index, emit_ofs + 0)); } - void Done5() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done5() { done_ = true; ok_ = false; } - void DecodeStep5() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep5() { if (!RefillTo1()) { Done6(); return; @@ -2355,236 +1886,171 @@ class HuffDecoder : public HuffDecoderCommon { const auto emit_ofs = op >> 1; sink_(GetEmit20(index, emit_ofs + 0)); } - void Done6() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done6() { done_ = true; ok_ = false; } - void DecodeStep6() { - if (!RefillTo1()) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep6() { + if (!RefillTo2()) { Done7(); return; } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; + const auto index = (buffer_ >> (buffer_len_ - 2)) & 0x3; const auto op = GetOp21(index); - const int consumed = op & 1; + const int consumed = op & 3; buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; + const auto emit_ofs = op >> 2; sink_(GetEmit21(index, emit_ofs + 0)); } - void Done7() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool RefillTo2() { + switch (buffer_len_) { + case 0: { + return Read1to8Bytes(); + } + case 1: { + return Read1to7Bytes(); + } + } + return true; + } + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done7() { done_ = true; - ok_ = false; + switch (buffer_len_) { + case 1: + case 0: { + ok_ = false; + return; + } + } } - void DecodeStep7() { - if (!RefillTo1()) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep7() { + if (!RefillTo2()) { Done8(); return; } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; + const auto index = (buffer_ >> (buffer_len_ - 2)) & 0x3; const auto op = GetOp22(index); - const int consumed = op & 1; + const int consumed = op & 3; buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; + const auto emit_ofs = op >> 2; sink_(GetEmit22(index, emit_ofs + 0)); } - void Done8() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done8() { done_ = true; - ok_ = false; + switch (buffer_len_) { + case 1: + case 0: { + ok_ = false; + return; + } + } } - void DecodeStep8() { - if (!RefillTo1()) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep8() { + if (!RefillTo2()) { Done9(); return; } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; + const auto index = (buffer_ >> (buffer_len_ - 2)) & 0x3; const auto op = GetOp23(index); - const int consumed = op & 1; + const int consumed = op & 3; buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; + const auto emit_ofs = op >> 2; sink_(GetEmit23(index, emit_ofs + 0)); } - void Done9() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done9() { done_ = true; - ok_ = false; + switch (buffer_len_) { + case 1: + case 0: { + ok_ = false; + return; + } + } } - void DecodeStep9() { - if (!RefillTo1()) { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep9() { + if (!RefillTo3()) { Done10(); return; } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; + const auto index = (buffer_ >> (buffer_len_ - 3)) & 0x7; const auto op = GetOp24(index); - const int consumed = op & 1; - buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; - sink_(GetEmit24(index, emit_ofs + 0)); - } - void Done10() { - done_ = true; - ok_ = false; - } - void DecodeStep10() { - if (!RefillTo1()) { - Done11(); - return; - } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp25(index); - const int consumed = op & 1; - buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; - sink_(GetEmit25(index, emit_ofs + 0)); - } - void Done11() { - done_ = true; - ok_ = false; - } - void DecodeStep11() { - if (!RefillTo1()) { - Done12(); - return; - } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp26(index); - const int consumed = op & 1; - buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; - sink_(GetEmit26(index, emit_ofs + 0)); - } - void Done12() { - done_ = true; - ok_ = false; - } - void DecodeStep12() { - if (!RefillTo1()) { - Done13(); - return; - } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp27(index); - const int consumed = op & 1; - buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; - sink_(GetEmit27(index, emit_ofs + 0)); - } - void Done13() { - done_ = true; - ok_ = false; - } - void DecodeStep13() { - if (!RefillTo1()) { - Done14(); - return; - } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp28(index); - const int consumed = op & 1; - buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; - sink_(GetEmit28(index, emit_ofs + 0)); - } - void Done14() { - done_ = true; - ok_ = false; - } - void DecodeStep14() { - if (!RefillTo1()) { - Done15(); - return; - } - const auto index = (buffer_ >> (buffer_len_ - 1)) & 0x1; - const auto op = GetOp29(index); - const int consumed = op & 1; - buffer_len_ -= consumed; - const auto emit_ofs = op >> 1; - sink_(GetEmit29(index, emit_ofs + 0)); - } - void Done15() { - done_ = true; - ok_ = false; - } - void DecodeStep15() { - if (!RefillTo2()) { - Done16(); - return; - } - const auto index = (buffer_ >> (buffer_len_ - 2)) & 0x3; - const auto op = GetOp30(index); const int consumed = op & 3; buffer_len_ -= consumed; const auto emit_ofs = op >> 2; - sink_(GetEmit30(index, emit_ofs + 0)); + sink_(GetEmit24(index, emit_ofs + 0)); } - bool RefillTo2() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool RefillTo3() { switch (buffer_len_) { case 0: { return Read1to8Bytes(); } - case 1: { + case 1: + case 2: { return Read1to7Bytes(); } } return true; } - void Done16() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done10() { done_ = true; switch (buffer_len_) { case 1: + case 2: case 0: { ok_ = false; return; } } } - void DecodeStep16() { - if (!RefillTo2()) { - Done17(); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep10() { + if (!RefillTo3()) { + Done11(); return; } - const auto index = (buffer_ >> (buffer_len_ - 2)) & 0x3; - const auto op = GetOp31(index); + const auto index = (buffer_ >> (buffer_len_ - 3)) & 0x7; + const auto op = GetOp25(index); const int consumed = op & 3; buffer_len_ -= consumed; const auto emit_ofs = op >> 2; - sink_(GetEmit31(index, emit_ofs + 0)); + sink_(GetEmit25(index, emit_ofs + 0)); } - void Done17() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done11() { done_ = true; switch (buffer_len_) { case 1: + case 2: case 0: { ok_ = false; return; } } } - void DecodeStep17() { - if (!RefillTo5()) { - Done18(); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep11() { + if (!RefillTo4()) { + Done12(); return; } - const auto index = (buffer_ >> (buffer_len_ - 5)) & 0x1f; - const auto op = GetOp32(index); + const auto index = (buffer_ >> (buffer_len_ - 4)) & 0xf; + const auto op = GetOp26(index); const int consumed = op & 7; buffer_len_ -= consumed; const auto emit_ofs = op >> 3; - sink_(GetEmit32(index, emit_ofs + 0)); + sink_(GetEmit26(index, emit_ofs + 0)); } - bool RefillTo5() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool RefillTo4() { switch (buffer_len_) { case 0: { return Read1to8Bytes(); } case 1: case 2: - case 3: - case 4: { + case 3: { return Read1to7Bytes(); } } return true; } - void Done18() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done12() { done_ = true; switch (buffer_len_) { case 1: @@ -2594,44 +2060,34 @@ class HuffDecoder : public HuffDecoderCommon { ok_ = false; return; } - case 4: { - const auto index = buffer_ & 15; - const auto op = GetOp33(index); - switch (op & 1) { - case 0: { - sink_(GetEmit33(index, (op >> 1) + 0)); - break; - } - case 1: { - ok_ = false; - break; - } - } - return; - } } } - void DecodeStep18() { - if (!RefillTo2()) { - Done19(); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep12() { + if (!RefillTo3()) { + Done13(); return; } - const auto index = (buffer_ >> (buffer_len_ - 2)) & 0x3; - const auto op = GetOp34(index); + const auto index = (buffer_ >> (buffer_len_ - 3)) & 0x7; + const auto op = GetOp27(index); const int consumed = op & 3; buffer_len_ -= consumed; const auto emit_ofs = op >> 2; - sink_(GetEmit34(index, emit_ofs + 0)); + sink_(GetEmit27(index, emit_ofs + 0)); } - void Done19() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done13() { done_ = true; switch (buffer_len_) { - case 1: { - const auto index = buffer_ & 1; - const auto op = GetOp35(index); + case 1: + case 0: { + ok_ = false; + return; + } + case 2: { + const auto index = buffer_ & 3; + const auto op = GetOp28(index); switch (op & 1) { case 0: { - sink_(GetEmit35(index, (op >> 1) + 0)); + sink_(GetEmit28(index, (op >> 1) + 0)); break; } case 1: { @@ -2641,50 +2097,35 @@ class HuffDecoder : public HuffDecoderCommon { } return; } - case 0: { - ok_ = false; - return; - } } } - void DecodeStep19() { - if (!RefillTo3()) { - Done20(); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep13() { + if (!RefillTo4()) { + Done14(); return; } - const auto index = (buffer_ >> (buffer_len_ - 3)) & 0x7; - const auto op = GetOp36(index); - const int consumed = op & 3; + const auto index = (buffer_ >> (buffer_len_ - 4)) & 0xf; + const auto op = GetOp29(index); + const int consumed = op & 7; buffer_len_ -= consumed; - const auto emit_ofs = op >> 2; - sink_(GetEmit36(index, emit_ofs + 0)); - } - bool RefillTo3() { - switch (buffer_len_) { - case 0: { - return Read1to8Bytes(); - } - case 1: - case 2: { - return Read1to7Bytes(); - } - } - return true; + const auto emit_ofs = op >> 3; + sink_(GetEmit29(index, emit_ofs + 0)); } - void Done20() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done14() { done_ = true; switch (buffer_len_) { case 1: + case 2: case 0: { ok_ = false; return; } - case 2: { - const auto index = buffer_ & 3; - const auto op = GetOp37(index); + case 3: { + const auto index = buffer_ & 7; + const auto op = GetOp30(index); switch (op & 1) { case 0: { - sink_(GetEmit37(index, (op >> 1) + 0)); + sink_(GetEmit30(index, (op >> 1) + 0)); break; } case 1: { @@ -2696,19 +2137,19 @@ class HuffDecoder : public HuffDecoderCommon { } } } - void DecodeStep20() { - if (!RefillTo8()) { - Done21(); + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void DecodeStep14() { + if (!RefillTo11()) { + Done15(); return; } - const auto index = (buffer_ >> (buffer_len_ - 8)) & 0xff; - const auto op = GetOp38(index); + const auto index = (buffer_ >> (buffer_len_ - 11)) & 0x7ff; + const auto op = GetOp31(index); const int consumed = op & 15; buffer_len_ -= consumed; const auto emit_ofs = op >> 5; switch ((op >> 4) & 1) { case 0: { - sink_(GetEmit38(index, emit_ofs + 0)); + sink_(GetEmit31(index, emit_ofs + 0)); break; } case 1: { @@ -2718,44 +2159,70 @@ class HuffDecoder : public HuffDecoderCommon { } } } - bool RefillTo8() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool RefillTo11() { switch (buffer_len_) { case 0: { - return Read1to8Bytes(); + return Read2to8Bytes(); } case 1: - case 2: + case 2: { + return Read2to7Bytes(); + } case 3: case 4: case 5: case 6: - case 7: { + case 7: + case 8: { return Read1to7Bytes(); } + case 9: + case 10: { + return Read1to6Bytes(); + } } return true; } - void Done21() { + GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Done15() { done_ = true; - switch (end_ - begin_) {} + switch (end_ - begin_) { + case 1: { + Fill1(); + break; + } + } switch (buffer_len_) { case 1: case 2: - case 3: - case 4: { + case 3: { ok_ = (buffer_ & ((1 << buffer_len_) - 1)) == (1 << buffer_len_) - 1; return; } + case 4: { + const auto index = buffer_ & 15; + const auto op = GetOp32(index); + switch (op & 3) { + case 0: { + sink_(GetEmit32(index, (op >> 2) + 0)); + break; + } + case 1: { + ok_ = false; + break; + } + } + return; + } case 5: { const auto index = buffer_ & 31; - const auto op = GetOp39(index); + const auto op = GetOp33(index); switch (op & 3) { case 0: { - sink_(GetEmit39(index, (op >> 2) + 0)); + ok_ = false; break; } case 1: { - ok_ = false; + sink_(GetEmit33(index, (op >> 2) + 0)); break; } } @@ -2763,14 +2230,14 @@ class HuffDecoder : public HuffDecoderCommon { } case 6: { const auto index = buffer_ & 63; - const auto op = GetOp40(index); + const auto op = GetOp34(index); switch (op & 3) { case 0: { ok_ = false; break; } case 1: { - sink_(GetEmit40(index, (op >> 2) + 0)); + sink_(GetEmit34(index, (op >> 2) + 0)); break; } } @@ -2778,14 +2245,69 @@ class HuffDecoder : public HuffDecoderCommon { } case 7: { const auto index = buffer_ & 127; - const auto op = GetOp41(index); + const auto op = GetOp35(index); switch (op & 3) { case 0: { ok_ = false; break; } case 1: { - sink_(GetEmit41(index, (op >> 2) + 0)); + sink_(GetEmit35(index, (op >> 2) + 0)); + break; + } + } + return; + } + case 8: { + const auto index = buffer_ & 255; + const auto op = GetOp36(index); + switch (op & 3) { + case 0: { + ok_ = false; + break; + } + case 1: { + sink_(GetEmit36(index, (op >> 2) + 0)); + break; + } + } + return; + } + case 9: { + const auto index = buffer_ & 511; + const auto op = GetOp37(index); + switch (op & 3) { + case 0: { + sink_(GetEmit37(index, (op >> 2) + 0)); + sink_(GetEmit37(index, (op >> 2) + 1)); + break; + } + case 1: { + ok_ = false; + break; + } + case 2: { + sink_(GetEmit37(index, (op >> 2) + 0)); + break; + } + } + return; + } + case 10: { + const auto index = buffer_ & 1023; + const auto op = GetOp38(index); + switch (op & 3) { + case 0: { + ok_ = false; + break; + } + case 1: { + sink_(GetEmit38(index, (op >> 2) + 0)); + sink_(GetEmit38(index, (op >> 2) + 1)); + break; + } + case 2: { + sink_(GetEmit38(index, (op >> 2) + 0)); break; } } diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/flow_control.h b/deps/grpc/src/core/ext/transport/chttp2/transport/flow_control.h index 0dd86dbaf58..54eb4a06cd6 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/flow_control.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/flow_control.h @@ -32,6 +32,7 @@ #include "absl/log/check.h" #include "absl/status/status.h" #include "absl/strings/string_view.h" +#include "src/core/channelz/property_list.h" #include "src/core/ext/transport/chttp2/transport/http2_settings.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/resource_quota/memory_quota.h" @@ -271,6 +272,11 @@ class TransportFlowControl final { FlowControlAction SetAckedInitialWindow(uint32_t value); + void set_target_initial_window_size(uint32_t value) { + target_initial_window_size_ = + std::min(value, Http2Settings::max_initial_window_size()); + } + // Getters int64_t remote_window() const { return remote_window_; } int64_t announced_window() const { return announced_window_; } @@ -302,23 +308,22 @@ class TransportFlowControl final { double bdp_bw_est; std::string ToString() const; - Json::Object ToJsonObject() { - Json::Object object; - object["targetWindow"] = Json::FromNumber(target_window); - object["targetFrameSize"] = Json::FromNumber(target_frame_size); - object["targetPreferredRxCryptoFrameSize"] = - Json::FromNumber(target_preferred_rx_crypto_frame_size); - object["ackedInitWindow"] = Json::FromNumber(acked_init_window); - object["queuedInitWindow"] = Json::FromNumber(queued_init_window); - object["sentInitWindow"] = Json::FromNumber(sent_init_window); - object["remoteWindow"] = Json::FromNumber(remote_window); - object["announcedWindow"] = Json::FromNumber(announced_window); - object["announcedStreamTotalOverIncomingWindow"] = - Json::FromNumber(announced_stream_total_over_incoming_window); - object["bdpAccumulator"] = Json::FromNumber(bdp_accumulator); - object["bdpEstimate"] = Json::FromNumber(bdp_estimate); - object["bdpBwEst"] = Json::FromNumber(bdp_bw_est); - return object; + channelz::PropertyList ChannelzProperties() const { + return channelz::PropertyList() + .Set("target_window", target_window) + .Set("target_frame_size", target_frame_size) + .Set("target_preferred_rx_crypto_frame_size", + target_preferred_rx_crypto_frame_size) + .Set("acked_init_window", acked_init_window) + .Set("queued_init_window", queued_init_window) + .Set("sent_init_window", sent_init_window) + .Set("remote_window", remote_window) + .Set("announced_window", announced_window) + .Set("announced_stream_total_over_incoming_window", + announced_stream_total_over_incoming_window) + .Set("bdp_accumulator", bdp_accumulator) + .Set("bdp_estimate", bdp_estimate) + .Set("bdp_bw_est", bdp_bw_est); } }; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/frame.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/frame.cc index 43c5c684ddf..95f90e40f8a 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/frame.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/frame.cc @@ -632,6 +632,16 @@ http2::ValueOrHttp2Status ParseFramePayload( } } +http2::Http2ErrorCode Http2ErrorCodeFromRstFrameErrorCode(uint32_t error_code) { + if (GPR_UNLIKELY(error_code > http2::GetMaxHttp2ErrorCode())) { + LOG(ERROR) << "Http2ErrorCodeFromRstFrameErrorCode: Invalid error code " + "received from RST_STREAM frame: " + << error_code; + return http2::Http2ErrorCode::kInternalError; + } + return static_cast(error_code); +} + GrpcMessageHeader ExtractGrpcHeader(SliceBuffer& payload) { CHECK_GE(payload.Length(), kGrpcHeaderSizeInBytes); uint8_t buffer[kGrpcHeaderSizeInBytes]; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/frame.h b/deps/grpc/src/core/ext/transport/chttp2/transport/frame.h index 72e3a904e5f..94a5f537783 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/frame.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/frame.h @@ -237,6 +237,8 @@ http2::ValueOrHttp2Status ParseFramePayload( // move things out of frames) void Serialize(absl::Span frames, SliceBuffer& out); +http2::Http2ErrorCode Http2ErrorCodeFromRstFrameErrorCode(uint32_t error_code); + /////////////////////////////////////////////////////////////////////////////// // GRPC Header @@ -321,8 +323,6 @@ inline constexpr absl::string_view kGoAwayLength8 = "GOAWAY frame should have a Last-Stream-ID and Error Code making the " "minimum length 8 octets"; -// TODO(tjagtap) : [PH2][P2] : Take care that our transport class does not make -// stream id larger than this. inline constexpr uint32_t kMaxStreamId31Bit = 0x7fffffffu; } // namespace RFC9113 diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/frame_data.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/frame_data.cc index 351afe9ea32..0eaeb4a600f 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -80,7 +80,7 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer* inbuf, grpc_slice_buffer_move_first_no_ref(inbuf, write_bytes, outbuf); - grpc_core::global_stats().IncrementHttp2WriteDataFrameSize(write_bytes); + grpc_core::http2_global_stats().IncrementHttp2WriteDataFrameSize(write_bytes); call_tracer->RecordOutgoingBytes({header_size, 0, 0}); } diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/frame_settings.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/frame_settings.cc index 515a0b4499b..e0e3e9eaa4a 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/frame_settings.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/frame_settings.cc @@ -108,19 +108,18 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p, if (is_last) { grpc_core::Http2Settings* target_settings = parser->incoming_settings.get(); - grpc_core::global_stats().IncrementHttp2HeaderTableSize( + t->http2_stats->IncrementHttp2HeaderTableSize( target_settings->header_table_size()); - grpc_core::global_stats().IncrementHttp2InitialWindowSize( + t->http2_stats->IncrementHttp2InitialWindowSize( target_settings->initial_window_size()); - grpc_core::global_stats().IncrementHttp2MaxConcurrentStreams( + t->http2_stats->IncrementHttp2MaxConcurrentStreams( target_settings->max_concurrent_streams()); - grpc_core::global_stats().IncrementHttp2MaxFrameSize( + t->http2_stats->IncrementHttp2MaxFrameSize( target_settings->max_frame_size()); - grpc_core::global_stats().IncrementHttp2MaxHeaderListSize( + t->http2_stats->IncrementHttp2MaxHeaderListSize( target_settings->max_header_list_size()); - grpc_core::global_stats() - .IncrementHttp2PreferredReceiveCryptoMessageSize( - target_settings->preferred_receive_crypto_message_size()); + t->http2_stats->IncrementHttp2PreferredReceiveCryptoMessageSize( + target_settings->preferred_receive_crypto_message_size()); t->http2_ztrace_collector.Append([parser]() { grpc_core::H2SettingsTrace settings{false, {}}; // TODO(ctiller): produce actual wire settings here, not a diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/frame_window_update.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/frame_window_update.cc index f4a61e73357..1403099d549 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/frame_window_update.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/frame_window_update.cc @@ -109,15 +109,14 @@ grpc_error_handle grpc_chttp2_window_update_parser_parse( if (s != nullptr) { grpc_core::Timestamp now = grpc_core::Timestamp::Now(); if (s->last_window_update_time != grpc_core::Timestamp::InfPast()) { - grpc_core::global_stats().IncrementHttp2StreamWindowUpdatePeriod( + t->http2_stats->IncrementHttp2StreamWindowUpdatePeriod( (now - s->last_window_update_time).millis()); } s->last_window_update_time = now; grpc_core::chttp2::StreamFlowControl::OutgoingUpdateContext( &s->flow_control) .RecvUpdate(received_update); - grpc_core::global_stats().IncrementHttp2StreamRemoteWindowUpdate( - received_update); + t->http2_stats->IncrementHttp2StreamRemoteWindowUpdate(received_update); if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) { grpc_chttp2_mark_stream_writable(t, s); grpc_chttp2_initiate_write( @@ -129,11 +128,11 @@ grpc_error_handle grpc_chttp2_window_update_parser_parse( &t->flow_control); grpc_core::Timestamp now = grpc_core::Timestamp::Now(); if (t->last_window_update_time != grpc_core::Timestamp::InfPast()) { - grpc_core::global_stats().IncrementHttp2TransportWindowUpdatePeriod( + t->http2_stats->IncrementHttp2TransportWindowUpdatePeriod( (now - t->last_window_update_time).millis()); } t->last_window_update_time = now; - grpc_core::global_stats().IncrementHttp2TransportRemoteWindowUpdate( + t->http2_stats->IncrementHttp2TransportRemoteWindowUpdate( received_update); upd.RecvUpdate(received_update); if (upd.Finish() == grpc_core::chttp2::StallEdge::kUnstalled) { diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/header_assembler.h b/deps/grpc/src/core/ext/transport/chttp2/transport/header_assembler.h index e1a72fcdc92..6415a3aac3f 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/header_assembler.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/header_assembler.h @@ -21,14 +21,19 @@ #include +#include +#include + #include "absl/log/check.h" #include "absl/log/log.h" #include "src/core/call/metadata_batch.h" #include "src/core/ext/transport/chttp2/transport/frame.h" +#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" #include "src/core/ext/transport/chttp2/transport/hpack_parser.h" #include "src/core/ext/transport/chttp2/transport/http2_status.h" #include "src/core/lib/slice/slice.h" #include "src/core/lib/slice/slice_buffer.h" +#include "src/core/util/shared_bit_gen.h" // TODO(tjagtap) TODO(akshitpatel): [PH2][P3] : Write micro benchmarks for // assembler and disassembler code @@ -36,19 +41,256 @@ namespace grpc_core { namespace http2 { +// If the Client Transport code is using HeaderAssembler in the wrong way, +// we fail with a DCHECK. +// If the peer sent some bad data, we fail with the appropriate Http2Status. + +#define ASSEMBLER_LOG DVLOG(3) + +constexpr absl::string_view kAssemblerContiguousSequenceError = + "RFC9113 : Field blocks MUST be transmitted as a contiguous sequence " + "of frames, with no interleaved frames of any other type or from any " + "other stream."; + +constexpr absl::string_view kAssemblerMismatchedStreamId = + "CONTINUATION frame has a different Stream Identifier than the preceeding " + "HEADERS frame."; + +constexpr absl::string_view kAssemblerHpackError = + "RFC9113 : A decoding error in a field block MUST be treated as a " + "connection error of type COMPRESSION_ERROR."; + +constexpr absl::string_view kGrpcErrorMaxTwoHeaderFrames = + "Too many header frames sent by peer"; + +// A gRPC server is permitted to send both initial metadata and trailing +// metadata where initial metadata is optional. A gRPC C++ client is permitted +// to send only initial metadata. However, other gRPC Client implementations may +// send trailing metadata too. So we allow only a maximum of 2 metadata per +// streams. Which means only 2 HEADER frames are legal per stream. +constexpr uint8_t kMaxHeaderFrames = 2; + +// TODO(tjagtap) : [PH2][P3] : Handle the case where a Server receives two +// header frames. Which means that the client sent trailing metadata. While we +// dont expect a gRPC C++ peer to behave like this, this might break interop +// tests and genuine interop cases. + +// RFC9113 +// https://www.rfc-editor.org/rfc/rfc9113.html#name-field-section-compression-a +// A complete field section (which contains our gRPC Metadata) consists of +// either: a single HEADERS or PUSH_PROMISE frame, with the END_HEADERS flag +// set, or a HEADERS or PUSH_PROMISE frame with the END_HEADERS flag unset +// and one or more CONTINUATION frames, where the last CONTINUATION frame +// has the END_HEADERS flag set. +// +// Each field block is processed as a discrete unit. Field blocks MUST be +// transmitted as a contiguous sequence of frames, with no interleaved +// frames of any other type or from any other stream. The last frame in a +// sequence of HEADERS or CONTINUATION frames has the END_HEADERS flag set. +// +// This class will first assemble all the header data into one SliceBuffer +// from each frame. And when END_HEADERS is received, the caller can generate +// the gRPC Metadata. class HeaderAssembler { public: - Http2ErrorCode AppendHeaderFrame(GRPC_UNUSED Http2HeaderFrame& frame) { - return Http2ErrorCode::kNoError; + // Call this for each incoming HTTP2 Header frame. + // The payload of the Http2HeaderFrame will be cleared in this function. + Http2Status AppendHeaderFrame(Http2HeaderFrame&& frame) { + // Validate input frame + DCHECK_GT(frame.stream_id, 0u) + << "RFC9113 : HEADERS frames MUST be associated with a stream."; + + // Manage size constraints + const size_t current_len = frame.payload.Length(); + if constexpr (sizeof(size_t) == 4) { + if (GPR_UNLIKELY(buffer_.Length() >= UINT32_MAX - current_len)) { + Cleanup(); + LOG(ERROR) + << "Stream Error: SliceBuffer overflow for 32 bit platforms."; + return Http2Status::Http2StreamError( + Http2ErrorCode::kInternalError, + "Stream Error: SliceBuffer overflow for 32 bit platforms."); + } + } + + // Start header workflow + header_in_progress_ = true; + + // Manage payload + frame.payload.MoveFirstNBytesIntoSliceBuffer(current_len, buffer_); + ASSEMBLER_LOG << "AppendHeaderFrame " << current_len << " Bytes."; + + // Manage if last frame + if (frame.end_headers) { + ASSEMBLER_LOG << "AppendHeaderFrame end_headers"; + is_ready_ = true; + } + + return Http2Status::Ok(); + } + + // Call this for each incoming HTTP2 Continuation frame. + // The payload of the Http2ContinuationFrame will be cleared in this function. + Http2Status AppendContinuationFrame(Http2ContinuationFrame&& frame) { + // Manage payload + const size_t current_len = frame.payload.Length(); + frame.payload.MoveFirstNBytesIntoSliceBuffer(current_len, buffer_); + ASSEMBLER_LOG << "AppendContinuationFrame " << current_len << " Bytes."; + + // Manage if last frame + if (frame.end_headers) { + ASSEMBLER_LOG << "AppendHeaderFrame end_headers"; + is_ready_ = true; + } + + return Http2Status::Ok(); + } + + // The caller MUST check using IsReady() before calling this function + ValueOrHttp2Status> ReadMetadata( + HPackParser& parser, bool is_initial_metadata, bool is_client) { + ASSEMBLER_LOG << "ReadMetadata " << buffer_.Length() << " Bytes."; + + // Validate + DCHECK_EQ(is_ready_, true); + + // Generate the gRPC Metadata from buffer_ + // RFC9113 : A receiver MUST terminate the connection with a connection + // error (Section 5.4.1) of type COMPRESSION_ERROR if it does not decompress + // a field block. A decoding error in a field block MUST be treated as a + // connection error (Section 5.4.1) of type COMPRESSION_ERROR. + Arena::PoolPtr metadata = + Arena::MakePooledForOverwrite(); + parser.BeginFrame( + /*grpc_metadata_batch*/ metadata.get(), + // TODO(tjagtap) : [PH2][P2] : Manage limits + /*metadata_size_soft_limit*/ std::numeric_limits::max(), + /*metadata_size_hard_limit*/ std::numeric_limits::max(), + is_initial_metadata ? HPackParser::Boundary::EndOfHeaders + : HPackParser::Boundary::EndOfStream, + HPackParser::Priority::None, + HPackParser::LogInfo{stream_id_, + is_initial_metadata + ? HPackParser::LogInfo::Type::kHeaders + : HPackParser::LogInfo::Type::kTrailers, + is_client}); + for (size_t i = 0; i < buffer_.Count(); i++) { + absl::Status result = parser.Parse( + buffer_.c_slice_at(i), i == buffer_.Count() - 1, SharedBitGen(), + /*call_tracer=*/nullptr); + if (GPR_UNLIKELY(!result.ok())) { + Cleanup(); + LOG(ERROR) << "Connection Error: " << kAssemblerHpackError; + return Http2Status::Http2ConnectionError( + Http2ErrorCode::kCompressionError, + std::string(kAssemblerHpackError)); + } + } + parser.FinishFrame(); + + Cleanup(); + + return ValueOrHttp2Status>( + std::move(metadata)); + } + + size_t GetBufferedHeadersLength() const { return buffer_.Length(); } + + // This value MUST be checked before calling ReadMetadata() + bool IsReady() const { return is_ready_; } + + explicit HeaderAssembler(const uint32_t stream_id) + : header_in_progress_(false), is_ready_(false), stream_id_(stream_id) {} + + ~HeaderAssembler() = default; + + HeaderAssembler(HeaderAssembler&& rvalue) = delete; + HeaderAssembler& operator=(HeaderAssembler&& rvalue) = delete; + HeaderAssembler(const HeaderAssembler&) = delete; + HeaderAssembler& operator=(const HeaderAssembler&) = delete; + + private: + void Cleanup() { + buffer_.Clear(); + header_in_progress_ = false; + is_ready_ = false; + } + + bool header_in_progress_; + bool is_ready_; + const uint32_t stream_id_; + SliceBuffer buffer_; +}; + +class HeaderDisassembler { + public: + // This function will take ownership of metadata object + // The method will return false if encoding fails. A failed encoding operation + // is MUST be treated as a connection error by the caller. + // This function can queue a trailing metadata for sending even before the + // initial metadata has been extracted. + bool PrepareForSending(Arena::PoolPtr&& metadata, + HPackCompressor& encoder) { + // Validate disassembler state + DCHECK(!is_done_); + // Prepare metadata for sending + return encoder.EncodeRawHeaders(*metadata.get(), buffer_); } - Http2ErrorCode AppendContinuationFrame( - GRPC_UNUSED Http2ContinuationFrame& frame) { - return Http2ErrorCode::kNoError; + Http2Frame GetNextFrame(const uint32_t max_frame_length, + bool& out_end_headers) { + if (buffer_.Length() == 0 || is_done_) { + DCHECK(false) << "Calling code must check size using HasMoreData() " + "before GetNextFrame()"; + } + out_end_headers = buffer_.Length() <= max_frame_length; + SliceBuffer temp; + if (out_end_headers) { + is_done_ = true; + temp.Swap(&buffer_); + } else { + buffer_.MoveFirstNBytesIntoSliceBuffer(max_frame_length, temp); + } + if (!did_send_header_frame_) { + did_send_header_frame_ = true; + return Http2HeaderFrame{stream_id_, out_end_headers, end_stream_, + std::move(temp)}; + } else { + return Http2ContinuationFrame{stream_id_, out_end_headers, + std::move(temp)}; + } } + bool HasMoreData() const { return !is_done_ && buffer_.Length() > 0; } + + // This number can be used for backpressure related calculations. + size_t GetBufferedLength() const { return buffer_.Length(); } + + // A separate HeaderDisassembler object MUST be made for Initial Metadata and + // Trailing Metadata + explicit HeaderDisassembler(const uint32_t stream_id, + const bool is_trailing_metadata) + : stream_id_(stream_id), + end_stream_(is_trailing_metadata), + did_send_header_frame_(false), + is_done_(false) {} + + ~HeaderDisassembler() = default; + + HeaderDisassembler(HeaderDisassembler&& rvalue) = delete; + HeaderDisassembler& operator=(HeaderDisassembler&& rvalue) = delete; + HeaderDisassembler(const HeaderDisassembler&) = delete; + HeaderDisassembler& operator=(const HeaderDisassembler&) = delete; + + size_t TestOnlyGetMainBufferLength() const { return buffer_.Length(); } + private: - GRPC_UNUSED uint32_t stream_id_; + const uint32_t stream_id_; + const bool end_stream_; + bool did_send_header_frame_; + bool is_done_; // Protect against the same disassembler from being used twice + + SliceBuffer buffer_; }; } // namespace http2 diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser.cc index 0482afbbcfa..f4b4f755641 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -1137,7 +1137,7 @@ grpc_error_handle HPackParser::ParseInput( input.bitsrc())) { HandleMetadataSoftSizeLimitExceeded(&input); } - global_stats().IncrementHttp2MetadataSize(state_.frame_length); + http2_global_stats().IncrementHttp2MetadataSize(state_.frame_length); if (call_tracer != nullptr && call_tracer->IsSampled() && metadata_buffer_ != nullptr) { MetadataSizesAnnotation metadata_sizes_annotation( diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc index b258e6ead09..e3bad58b655 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc @@ -33,6 +33,7 @@ #include "absl/strings/string_view.h" #include "src/core/ext/transport/chttp2/transport/hpack_constants.h" #include "src/core/ext/transport/chttp2/transport/hpack_parse_result.h" +#include "src/core/ext/transport/chttp2/transport/http2_stats_collector.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/slice/slice.h" #include "src/core/telemetry/stats.h" @@ -58,7 +59,7 @@ auto HPackTable::MementoRingBuffer::PopOne() -> Memento { CHECK_GT(num_entries_, 0u); size_t index = first_entry_ % max_entries_; if (index == timestamp_index_) { - global_stats().IncrementHttp2HpackEntryLifetime( + http2_stats_collector_->IncrementHttp2HpackEntryLifetime( (Timestamp::Now() - timestamp_).millis()); timestamp_index_ = kNoTimestamp; } @@ -66,7 +67,7 @@ auto HPackTable::MementoRingBuffer::PopOne() -> Memento { --num_entries_; auto& entry = entries_[index]; if (!entry.parse_status.TestBit(Memento::kUsedBit)) { - global_stats().IncrementHttp2HpackMisses(); + http2_stats_collector_->IncrementHttp2HpackMisses(); } return std::move(entry); } @@ -77,7 +78,7 @@ auto HPackTable::MementoRingBuffer::Lookup(uint32_t index) -> const Memento* { auto& entry = entries_[offset]; const bool was_used = entry.parse_status.TestBit(Memento::kUsedBit); entry.parse_status.SetBit(Memento::kUsedBit); - if (!was_used) global_stats().IncrementHttp2HpackHits(); + if (!was_used) http2_stats_collector_->IncrementHttp2HpackHits(); return &entry; } @@ -110,9 +111,9 @@ void HPackTable::MementoRingBuffer::ForEach(F f) const { } HPackTable::MementoRingBuffer::~MementoRingBuffer() { - ForEach([](uint32_t, const Memento& m) { + ForEach([this](uint32_t, const Memento& m) { if (!m.parse_status.TestBit(Memento::kUsedBit)) { - global_stats().IncrementHttp2HpackMisses(); + http2_stats_collector_->IncrementHttp2HpackMisses(); } }); } @@ -124,6 +125,11 @@ void HPackTable::EvictOne() { mem_used_ -= first_entry.md.transport_size(); } +void HPackTable::SetHttp2StatsCollector( + std::shared_ptr http2_stats_collector) { + entries_.SetHttp2StatsCollector(http2_stats_collector); +} + void HPackTable::SetMaxBytes(uint32_t max_bytes) { if (max_bytes_ == max_bytes) { return; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.h b/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.h index 5c3f3e505e1..96a1514674a 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/hpack_parser_table.h @@ -33,6 +33,7 @@ #include "src/core/call/parsed_metadata.h" #include "src/core/ext/transport/chttp2/transport/hpack_constants.h" #include "src/core/ext/transport/chttp2/transport/hpack_parse_result.h" +#include "src/core/ext/transport/chttp2/transport/http2_stats_collector.h" #include "src/core/util/no_destruct.h" #include "src/core/util/unique_ptr_with_bitset.h" @@ -49,6 +50,8 @@ class HPackTable { HPackTable(HPackTable&&) = default; HPackTable& operator=(HPackTable&&) = default; + void SetHttp2StatsCollector( + std::shared_ptr http2_stats_collector); void SetMaxBytes(uint32_t max_bytes); bool SetCurrentTableSize(uint32_t bytes); uint32_t current_table_size() { return current_table_bytes_; } @@ -101,7 +104,8 @@ class HPackTable { class MementoRingBuffer { public: - MementoRingBuffer() {} + MementoRingBuffer() + : http2_stats_collector_(CreateHttp2StatsCollector(nullptr)) {} ~MementoRingBuffer(); MementoRingBuffer(const MementoRingBuffer&) = delete; @@ -109,6 +113,11 @@ class HPackTable { MementoRingBuffer(MementoRingBuffer&&) = default; MementoRingBuffer& operator=(MementoRingBuffer&&) = default; + void SetHttp2StatsCollector( + std::shared_ptr http2_stats_collector) { + http2_stats_collector_ = http2_stats_collector; + } + // Rebuild this buffer with a new max_entries_ size. void Rebuild(uint32_t max_entries); @@ -146,6 +155,8 @@ class HPackTable { // The timestamp associated with timestamp_entry_. Timestamp timestamp_; + std::shared_ptr http2_stats_collector_ = nullptr; + std::vector entries_; }; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.cc index e5e0fcda069..157da63d568 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.cc @@ -30,8 +30,15 @@ #include "absl/log/log.h" #include "absl/status/status.h" #include "src/core/call/call_spine.h" +#include "src/core/call/message.h" +#include "src/core/call/metadata_batch.h" #include "src/core/ext/transport/chttp2/transport/frame.h" +#include "src/core/ext/transport/chttp2/transport/header_assembler.h" +#include "src/core/ext/transport/chttp2/transport/http2_settings.h" +#include "src/core/ext/transport/chttp2/transport/http2_status.h" #include "src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h" +#include "src/core/ext/transport/chttp2/transport/message_assembler.h" +#include "src/core/ext/transport/chttp2/transport/transport_common.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/promise/for_each.h" @@ -62,90 +69,277 @@ using grpc_event_engine::experimental::EventEngine; // TODO(tjagtap) : [PH2][P3] : Delete this comment when http2 // rollout begins -void Http2ClientTransport::PerformOp(GRPC_UNUSED grpc_transport_op* op) { - HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp Begin"; - // TODO(tjagtap) : [PH2][P1] : Implement this function. - HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp End"; +void Http2ClientTransport::PerformOp(grpc_transport_op* op) { + // Notes : Refer : src/core/ext/transport/chaotic_good/client_transport.cc + // Functions : StartConnectivityWatch, StopConnectivityWatch, PerformOp + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp Begin"; + bool did_stuff = false; + if (op->start_connectivity_watch != nullptr) { + StartConnectivityWatch(op->start_connectivity_watch_state, + std::move(op->start_connectivity_watch)); + did_stuff = true; + } + if (op->stop_connectivity_watch != nullptr) { + StopConnectivityWatch(op->stop_connectivity_watch); + did_stuff = true; + } + CHECK(!op->set_accept_stream) << "Set_accept_stream not supported on clients"; + DCHECK(did_stuff) << "Unimplemented transport perform op "; + + ExecCtx::Run(DEBUG_LOCATION, op->on_consumed, absl::OkStatus()); + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp End"; + // TODO(tjagtap) : [PH2][P2] : + // Refer src/core/ext/transport/chttp2/transport/chttp2_transport.cc + // perform_transport_op_locked + // Maybe more operations needed to be implemented. + // TODO(tjagtap) : [PH2][P2] : Consider either not using a transport level + // lock, or making this run on the Transport party - whatever is better. +} + +void Http2ClientTransport::StartConnectivityWatch( + grpc_connectivity_state state, + OrphanablePtr watcher) { + MutexLock lock(&transport_mutex_); + state_tracker_.AddWatcher(state, std::move(watcher)); +} + +void Http2ClientTransport::StopConnectivityWatch( + ConnectivityStateWatcherInterface* watcher) { + MutexLock lock(&transport_mutex_); + state_tracker_.RemoveWatcher(watcher); } void Http2ClientTransport::Orphan() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan Begin"; - // TODO(tjagtap) : [PH2][P1] : Implement the needed cleanup - general_party_.reset(); + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan Begin"; + // Accessing general_party here is not advisable. It may so happen that + // the party is already freed/may free up any time. The only guarantee here + // is that the transport is still valid. + MaybeSpawnCloseTransport(Http2Status::AbslConnectionError( + absl::StatusCode::kUnavailable, "Orphaned")); Unref(); - HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan End"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan End"; } void Http2ClientTransport::AbortWithError() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError Begin"; - // TODO(tjagtap) : [PH2][P1] : Implement this function. - HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError End"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError Begin"; + // TODO(tjagtap) : [PH2][P2] : Implement this function. + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError End"; } /////////////////////////////////////////////////////////////////////////////// -// Promise factory for processing each type of frame +// Processing each type of frame Http2Status Http2ClientTransport::ProcessHttp2DataFrame(Http2DataFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-data - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2DataFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_TRANSPORT_DLOG - << "Http2Transport ProcessHttp2DataFrame Promise { stream_id=" - << frame.stream_id << ", end_stream=" << frame.end_stream - << ", payload=" << frame.payload.JoinIntoString() << "}"; + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2DataFrame { stream_id=" + << frame.stream_id + << ", end_stream=" << frame.end_stream + << ", payload=" << frame.payload.JoinIntoString() + << "}"; + + // TODO(akshitpatel) : [PH2][P3] : Investigate if we should do this even if + // the function returns a non-ok status? ping_manager_.ReceivedDataFrame(); + + // Lookup stream + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2DataFrame LookupStream"; + RefCountedPtr stream = LookupStream(frame.stream_id); + if (stream == nullptr) { + // TODO(tjagtap) : [PH2][P2] : Implement the correct behaviour later. + // RFC9113 : If a DATA frame is received whose stream is not in the "open" + // or "half-closed (local)" state, the recipient MUST respond with a stream + // error (Section 5.4.2) of type STREAM_CLOSED. + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2DataFrame { stream_id=" + << frame.stream_id << "} Lookup Failed"; + return Http2Status::Ok(); + } + + // Add frame to assembler + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2DataFrame AppendNewDataFrame"; + GrpcMessageAssembler& assembler = stream->assembler; + Http2Status status = + assembler.AppendNewDataFrame(frame.payload, frame.end_stream); + if (!status.IsOk()) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2DataFrame AppendNewDataFrame Failed"; + return status; + } + + // Pass the messages up the stack if it is ready. + while (true) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2DataFrame ExtractMessage"; + ValueOrHttp2Status result = assembler.ExtractMessage(); + if (!result.IsOk()) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2DataFrame ExtractMessage Failed"; + return ValueOrHttp2Status::TakeStatus(std::move(result)); + } + MessageHandle message = TakeValue(std::move(result)); + if (message != nullptr) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2DataFrame SpawnPushMessage " + << message->DebugString(); + stream->call.SpawnPushMessage(std::move(message)); + continue; + } + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2DataFrame While Break"; + break; + } + + // TODO(tjagtap) : [PH2][P2] : List of Tests: + // 1. Data frame with unknown stream ID + // 2. Data frame with only half a message and then end stream + // 3. One data frame with a full message + // 4. Three data frames with one full message + // 5. One data frame with three full messages. All messages should be pushed. + // Will need to mock the call_handler object and test this along with the + // Header reading code. Because we need a stream in place for the lookup to + // work. return Http2Status::Ok(); } Http2Status Http2ClientTransport::ProcessHttp2HeaderFrame( Http2HeaderFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-headers - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2HeaderFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_TRANSPORT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2HeaderFrame Promise { stream_id=" << frame.stream_id << ", end_headers=" << frame.end_headers << ", end_stream=" << frame.end_stream << ", payload=" << frame.payload.JoinIntoString() << " }"; ping_manager_.ReceivedDataFrame(); + + RefCountedPtr stream = + LookupStream(frame.stream_id); + if (stream == nullptr) { + // TODO(tjagtap) : [PH2][P3] : Implement this. + // RFC9113 : The identifier of a newly established stream MUST be + // numerically greater than all streams that the initiating endpoint has + // opened or reserved. This governs streams that are opened using a HEADERS + // frame and streams that are reserved using PUSH_PROMISE. An endpoint that + // receives an unexpected stream identifier MUST respond with a connection + // error (Section 5.4.1) of type PROTOCOL_ERROR. + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2HeaderFrame Promise { stream_id=" + << frame.stream_id << "} Lookup Failed"; + return Http2Status::Ok(); + } + + incoming_header_in_progress_ = !frame.end_headers; + incoming_header_stream_id_ = frame.stream_id; + incoming_header_end_stream_ = frame.end_stream; + if ((incoming_header_end_stream_ && stream->did_push_trailing_metadata) || + (!incoming_header_end_stream_ && stream->did_push_initial_metadata)) { + return Http2Status::Http2StreamError( + Http2ErrorCode::kInternalError, + "gRPC Error : A gRPC server can send upto 1 initial metadata followed " + "by upto 1 trailing metadata"); + } + + HeaderAssembler& assembler = stream->header_assembler; + Http2Status append_result = assembler.AppendHeaderFrame(std::move(frame)); + if (append_result.IsOk()) { + return ProcessMetadata(stream->stream_id, assembler, stream->call, + stream->did_push_initial_metadata, + stream->did_push_trailing_metadata); + } + return append_result; +} + +Http2Status Http2ClientTransport::ProcessMetadata( + uint32_t stream_id, HeaderAssembler& assembler, CallHandler& call, + bool& did_push_initial_metadata, bool& did_push_trailing_metadata) { + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessMetadata"; + if (assembler.IsReady()) { + ValueOrHttp2Status> read_result = + assembler.ReadMetadata(parser_, !incoming_header_end_stream_, + /*is_client=*/true); + if (read_result.IsOk()) { + Arena::PoolPtr metadata = + TakeValue(std::move(read_result)); + if (incoming_header_end_stream_) { + // TODO(tjagtap) : [PH2][P1] : Is this the right way to differentiate + // between initial and trailing metadata? + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessMetadata SpawnPushServerTrailingMetadata"; + did_push_trailing_metadata = true; + call.SpawnPushServerTrailingMetadata(std::move(metadata)); + CloseStream(stream_id, absl::OkStatus(), + CloseStreamArgs{ + /*close_reads=*/true, + /*close_writes=*/true, + /*send_rst_stream=*/false, + /*should_not_push_trailers=*/true, + }); + + } else { + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessMetadata SpawnPushServerInitialMetadata"; + did_push_initial_metadata = true; + call.SpawnPushServerInitialMetadata(std::move(metadata)); + } + return Http2Status::Ok(); + } + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessMetadata Failed"; + return ValueOrHttp2Status>::TakeStatus( + std::move(read_result)); + } return Http2Status::Ok(); } Http2Status Http2ClientTransport::ProcessHttp2RstStreamFrame( Http2RstStreamFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-rst_stream - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2RstStreamFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_TRANSPORT_DLOG - << "Http2Transport ProcessHttp2RstStreamFrame Promise{ stream_id=" + GRPC_HTTP2_CLIENT_DLOG + << "Http2Transport ProcessHttp2RstStreamFrame { stream_id=" << frame.stream_id << ", error_code=" << frame.error_code << " }"; + Http2ErrorCode error_code = + Http2ErrorCodeFromRstFrameErrorCode(frame.error_code); + CloseStream(frame.stream_id, + absl::Status((ErrorCodeToAbslStatusCode(error_code)), + "Reset stream frame received."), + CloseStreamArgs{ + /*close_reads=*/true, + /*close_writes=*/true, + /*send_rst_stream=*/false, + /*push_trailing_metadata=*/true, + }); + // In case of stream error, we do not want the Read Loop to be broken. Hence + // returning an ok status. return Http2Status::Ok(); } Http2Status Http2ClientTransport::ProcessHttp2SettingsFrame( Http2SettingsFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-settings - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2SettingsFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SettingsFrame Factory"; + // TODO(tjagtap) : [PH2][P2] : Implement this. // Load into this.settings_ // Take necessary actions as per settings that have changed. - HTTP2_TRANSPORT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SettingsFrame Promise { ack=" << frame.ack << ", settings length=" << frame.settings.size() << "}"; + if (on_receive_settings_ != nullptr) { + ExecCtx::Run(DEBUG_LOCATION, on_receive_settings_, absl::OkStatus()); + on_receive_settings_ = nullptr; + } return Http2Status::Ok(); } auto Http2ClientTransport::ProcessHttp2PingFrame(Http2PingFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-ping - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2PingFrame { ack=" - << frame.ack << ", opaque=" << frame.opaque << " }"; + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2PingFrame { ack=" + << frame.ack << ", opaque=" << frame.opaque << " }"; return AssertResultType(If( frame.ack, [self = RefAsSubclass(), opaque = frame.opaque]() { // Received a ping ack. if (!self->ping_manager_.AckPing(opaque)) { - HTTP2_TRANSPORT_DLOG << "Unknown ping resoponse received for ping id=" - << opaque; + GRPC_HTTP2_CLIENT_DLOG + << "Unknown ping response received for ping id=" << opaque; } return Immediate(Http2Status::Ok()); }, @@ -161,37 +355,36 @@ auto Http2ClientTransport::ProcessHttp2PingFrame(Http2PingFrame frame) { // ProcessFrame promises may return stream or connection failures. If // this does not turn out to be true, consider returning absl::Status // here. - return Map(self->EnqueueOutgoingFrame(Http2EmptyFrame{}), - [](absl::Status status) { - return (status.ok()) ? Http2Status::Ok() - : Http2Status::AbslConnectionError( - status.code(), - std::string(status.message())); - }); + return Map(self->TriggerWriteCycle(), [](absl::Status status) { + return (status.ok()) + ? Http2Status::Ok() + : Http2Status::AbslConnectionError( + status.code(), std::string(status.message())); + }); })); } Http2Status Http2ClientTransport::ProcessHttp2GoawayFrame( Http2GoawayFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-goaway - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Promise { " - "last_stream_id=" - << frame.last_stream_id - << ", error_code=" << frame.error_code - << ", debug_data=" << frame.debug_data.as_string_view() - << "}"; + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Factory"; + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Promise { " + "last_stream_id=" + << frame.last_stream_id + << ", error_code=" << frame.error_code + << ", debug_data=" << frame.debug_data.as_string_view() + << "}"; return Http2Status::Ok(); } Http2Status Http2ClientTransport::ProcessHttp2WindowUpdateFrame( Http2WindowUpdateFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-window_update - HTTP2_TRANSPORT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2WindowUpdateFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_TRANSPORT_DLOG + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2WindowUpdateFrame Promise { " " stream_id=" << frame.stream_id << ", increment=" << frame.increment << "}"; @@ -201,56 +394,77 @@ Http2Status Http2ClientTransport::ProcessHttp2WindowUpdateFrame( Http2Status Http2ClientTransport::ProcessHttp2ContinuationFrame( Http2ContinuationFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-continuation - HTTP2_TRANSPORT_DLOG - << "Http2Transport ProcessHttp2ContinuationFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_TRANSPORT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2ContinuationFrame Promise { " "stream_id=" << frame.stream_id << ", end_headers=" << frame.end_headers << ", payload=" << frame.payload.JoinIntoString() << " }"; - return Http2Status::Ok(); + incoming_header_in_progress_ = !frame.end_headers; + RefCountedPtr stream = LookupStream(frame.stream_id); + if (stream == nullptr) { + // TODO(tjagtap) : [PH2][P3] : Implement this. + // RFC9113 : The identifier of a newly established stream MUST be + // numerically greater than all streams that the initiating endpoint has + // opened or reserved. This governs streams that are opened using a HEADERS + // frame and streams that are reserved using PUSH_PROMISE. An endpoint that + // receives an unexpected stream identifier MUST respond with a connection + // error (Section 5.4.1) of type PROTOCOL_ERROR. + return Http2Status::Ok(); + } + + HeaderAssembler& assember = stream->header_assembler; + Http2Status result = assember.AppendContinuationFrame(std::move(frame)); + if (result.IsOk()) { + return ProcessMetadata(stream->stream_id, assember, stream->call, + stream->did_push_initial_metadata, + stream->did_push_trailing_metadata); + } + return result; } Http2Status Http2ClientTransport::ProcessHttp2SecurityFrame( Http2SecurityFrame frame) { - // TODO(tjagtap) : [PH2][P2] : This is not in the RFC. Understand usage. - HTTP2_TRANSPORT_DLOG << "Http2Transport ProcessHttp2SecurityFrame Factory"; + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SecurityFrame Factory"; // TODO(tjagtap) : [PH2][P2] : Implement this. - HTTP2_TRANSPORT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SecurityFrame Promise { payload=" << frame.payload.JoinIntoString() << " }"; return Http2Status::Ok(); } auto Http2ClientTransport::ProcessOneFrame(Http2Frame frame) { - HTTP2_CLIENT_DLOG << "Http2ClientTransport ProcessOneFrame Factory"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ProcessOneFrame Factory"; return AssertResultType(MatchPromise( std::move(frame), - [this](Http2DataFrame frame) { - return ProcessHttp2DataFrame(std::move(frame)); + [self = RefAsSubclass()](Http2DataFrame frame) { + return self->ProcessHttp2DataFrame(std::move(frame)); + }, + [self = RefAsSubclass()](Http2HeaderFrame frame) { + return self->ProcessHttp2HeaderFrame(std::move(frame)); }, - [this](Http2HeaderFrame frame) { - return ProcessHttp2HeaderFrame(std::move(frame)); + [self = + RefAsSubclass()](Http2RstStreamFrame frame) { + return self->ProcessHttp2RstStreamFrame(frame); }, - [this](Http2RstStreamFrame frame) { - return ProcessHttp2RstStreamFrame(frame); + [self = RefAsSubclass()](Http2SettingsFrame frame) { + return self->ProcessHttp2SettingsFrame(std::move(frame)); }, - [this](Http2SettingsFrame frame) { - return ProcessHttp2SettingsFrame(std::move(frame)); + [self = RefAsSubclass()](Http2PingFrame frame) { + return self->ProcessHttp2PingFrame(frame); }, - [this](Http2PingFrame frame) { return ProcessHttp2PingFrame(frame); }, - [this](Http2GoawayFrame frame) { - return ProcessHttp2GoawayFrame(std::move(frame)); + [self = RefAsSubclass()](Http2GoawayFrame frame) { + return self->ProcessHttp2GoawayFrame(std::move(frame)); }, - [this](Http2WindowUpdateFrame frame) { - return ProcessHttp2WindowUpdateFrame(frame); + [self = RefAsSubclass()]( + Http2WindowUpdateFrame frame) { + return self->ProcessHttp2WindowUpdateFrame(frame); }, - [this](Http2ContinuationFrame frame) { - return ProcessHttp2ContinuationFrame(std::move(frame)); + [self = RefAsSubclass()]( + Http2ContinuationFrame frame) { + return self->ProcessHttp2ContinuationFrame(std::move(frame)); }, - [this](Http2SecurityFrame frame) { - return ProcessHttp2SecurityFrame(std::move(frame)); + [self = RefAsSubclass()](Http2SecurityFrame frame) { + return self->ProcessHttp2SecurityFrame(std::move(frame)); }, [](GRPC_UNUSED Http2UnknownFrame frame) { // As per HTTP2 RFC, implementations MUST ignore and discard frames of @@ -268,90 +482,118 @@ auto Http2ClientTransport::ProcessOneFrame(Http2Frame frame) { // Read Related Promises and Promise Factories auto Http2ClientTransport::ReadAndProcessOneFrame() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame Factory"; + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport ReadAndProcessOneFrame Factory"; return AssertResultType(TrySeq( // Fetch the first kFrameHeaderSize bytes of the Frame, these contain // the frame header. - endpoint_.ReadSlice(kFrameHeaderSize), + EndpointReadSlice(kFrameHeaderSize), // Parse the frame header. [](Slice header_bytes) -> Http2FrameHeader { - HTTP2_CLIENT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame Parse " << header_bytes.as_string_view(); return Http2FrameHeader::Parse(header_bytes.begin()); }, + // Validate the incoming frame as per the current state of the transport + [self = RefAsSubclass()](Http2FrameHeader header) { + if (self->incoming_header_in_progress_ && + (self->current_frame_header_.type != 9 /*Continuation*/ || + self->current_frame_header_.stream_id != + self->incoming_header_stream_id_)) { + LOG(ERROR) << "Closing Connection " << header.ToString() << " " + << kAssemblerContiguousSequenceError; + return self->HandleError(Http2Status::Http2ConnectionError( + Http2ErrorCode::kProtocolError, + std::string(kAssemblerContiguousSequenceError))); + } + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame " + "Validated Frame Header:" + << header.ToString(); + self->current_frame_header_ = header; + return absl::OkStatus(); + }, // Read the payload of the frame. - [this](Http2FrameHeader header) { - // TODO(tjagtap) : [PH2][P3] : This is not nice. Fix by using Stapler. - HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame Read"; - current_frame_header_ = header; + [self = RefAsSubclass()]() { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport ReadAndProcessOneFrame Read Frame "; return AssertResultType>( - endpoint_.Read(header.length)); + self->EndpointRead(self->current_frame_header_.length)); }, // Parse the payload of the frame based on frame type. - [this](SliceBuffer payload) -> absl::StatusOr { - HTTP2_CLIENT_DLOG + [self = RefAsSubclass()]( + SliceBuffer payload) -> absl::StatusOr { + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame ParseFramePayload " << payload.JoinIntoString(); ValueOrHttp2Status frame = - ParseFramePayload(current_frame_header_, std::move(payload)); + ParseFramePayload(self->current_frame_header_, std::move(payload)); if (!frame.IsOk()) { - return HandleError( + return self->HandleError( ValueOrHttp2Status::TakeStatus(std::move(frame))); } - return TakeValue(std::move(frame)); }, - [this](GRPC_UNUSED Http2Frame frame) { - HTTP2_CLIENT_DLOG + [self = RefAsSubclass()]( + GRPC_UNUSED Http2Frame frame) { + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame ProcessOneFrame"; - return AssertResultType(Map( - ProcessOneFrame(std::move(frame)), - [self = RefAsSubclass()](Http2Status status) { - if (!status.IsOk()) { - return self->HandleError(std::move(status)); - } - - return absl::OkStatus(); - })); + return AssertResultType( + Map(self->ProcessOneFrame(std::move(frame)), + [self](Http2Status status) { + if (!status.IsOk()) { + return self->HandleError(std::move(status)); + } + return absl::OkStatus(); + })); })); } auto Http2ClientTransport::ReadLoop() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadLoop Factory"; - return AssertResultType(Loop([this]() { - return TrySeq(ReadAndProcessOneFrame(), []() -> LoopCtl { - HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadLoop Continue"; - return Continue(); - }); - })); + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadLoop Factory"; + return AssertResultType( + Loop([self = RefAsSubclass()]() { + return TrySeq(self->ReadAndProcessOneFrame(), + []() -> LoopCtl { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport ReadLoop Continue"; + return Continue(); + }); + })); } auto Http2ClientTransport::OnReadLoopEnded() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport OnReadLoopEnded Factory"; - return [self = RefAsSubclass()](absl::Status status) { - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_CLIENT_DLOG << "Http2ClientTransport OnReadLoopEnded Promise Status=" - << status; - GRPC_UNUSED absl::Status error = - self->HandleError(Http2Status::AbslConnectionError( - status.code(), std::string(status.message()))); - }; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport OnReadLoopEnded Factory"; + return + [self = RefAsSubclass()](absl::Status status) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport OnReadLoopEnded Promise Status=" << status; + GRPC_UNUSED absl::Status error = + self->HandleError(Http2Status::AbslConnectionError( + status.code(), std::string(status.message()))); + }; } /////////////////////////////////////////////////////////////////////////////// // Write Related Promises and Promise Factories auto Http2ClientTransport::WriteFromQueue() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Factory"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Factory"; return TrySeq( - outgoing_frames_.NextBatch(), + outgoing_frames_.NextBatch(128), [self = RefAsSubclass()]( std::vector frames) { SliceBuffer output_buf; + if (self->is_first_write_) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport Write GRPC_CHTTP2_CLIENT_CONNECT_STRING"; + output_buf.Append(Slice(grpc_slice_from_copied_string( + GRPC_CHTTP2_CLIENT_CONNECT_STRING))); + self->is_first_write_ = false; + } Serialize(absl::Span(frames), output_buf); uint64_t buffer_length = output_buf.Length(); - HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Promise"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Promise"; return If( buffer_length > 0, [self, output_buffer = std::move(output_buf)]() mutable { @@ -364,48 +606,47 @@ auto Http2ClientTransport::WriteFromQueue() { } auto Http2ClientTransport::WriteLoop() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteLoop Factory"; - return AssertResultType(Loop([this]() { - // TODO(akshitpatel) : [PH2][P1] : Once a common SliceBuffer is used, we - // can move bytes_sent_in_last_write_ to be a local variable. - bytes_sent_in_last_write_ = false; - return TrySeq( - // TODO(akshitpatel) : [PH2][P1] : WriteFromQueue may write settings - // acks as well. This will break the call to ResetPingClock as it only - // needs to be called on writing Data/Header/WindowUpdate frames. - // Possible fixes: Either WriteFromQueue iterates over all the frames - // and figures out the types of frames needed (this may anyways be - // needed to check that we do not send frames for closed streams) or we - // have flags to indicate the types of frame that are enqueued. - WriteFromQueue(), - [self = RefAsSubclass()] { - return self->MaybeSendPing(); - }, - [self = RefAsSubclass()] { - return self->MaybeSendPingAcks(); - }, - [this]() -> LoopCtl { - // If any Header/Data/WindowUpdate frame was sent in the last write, - // reset the ping clock. - if (bytes_sent_in_last_write_) { - ping_manager_.ResetPingClock(/*is_client=*/true); - } - HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteLoop Continue"; - return Continue(); - }); - })); + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteLoop Factory"; + return AssertResultType( + Loop([self = RefAsSubclass()]() { + // TODO(akshitpatel) : [PH2][P1] : Once a common SliceBuffer is used, we + // can move bytes_sent_in_last_write_ to be a local variable. + self->bytes_sent_in_last_write_ = false; + return TrySeq( + // TODO(akshitpatel) : [PH2][P1] : WriteFromQueue may write settings + // acks as well. This will break the call to ResetPingClock as it + // only needs to be called on writing Data/Header/WindowUpdate + // frames. Possible fixes: Either WriteFromQueue iterates over all + // the frames and figures out the types of frames needed (this may + // anyways be needed to check that we do not send frames for closed + // streams) or we have flags to indicate the types of frame that are + // enqueued. + self->WriteFromQueue(), [self] { return self->MaybeSendPing(); }, + [self] { return self->MaybeSendPingAcks(); }, + [self]() -> LoopCtl { + // If any Header/Data/WindowUpdate frame was sent in the last + // write, reset the ping clock. + if (self->bytes_sent_in_last_write_) { + self->ping_manager_.ResetPingClock(/*is_client=*/true); + } + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport WriteLoop Continue"; + return Continue(); + }); + })); } auto Http2ClientTransport::OnWriteLoopEnded() { - HTTP2_CLIENT_DLOG << "Http2ClientTransport OnWriteLoopEnded Factory"; - return [self = RefAsSubclass()](absl::Status status) { - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_CLIENT_DLOG << "Http2ClientTransport OnWriteLoopEnded Promise Status=" - << status; - GRPC_UNUSED absl::Status error = - self->HandleError(Http2Status::AbslConnectionError( - status.code(), std::string(status.message()))); - }; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport OnWriteLoopEnded Factory"; + return + [self = RefAsSubclass()](absl::Status status) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport OnWriteLoopEnded Promise Status=" + << status; + GRPC_UNUSED absl::Status error = + self->HandleError(Http2Status::AbslConnectionError( + status.code(), std::string(status.message()))); + }; } /////////////////////////////////////////////////////////////////////////////// @@ -413,15 +654,31 @@ auto Http2ClientTransport::OnWriteLoopEnded() { Http2ClientTransport::Http2ClientTransport( PromiseEndpoint endpoint, GRPC_UNUSED const ChannelArgs& channel_args, - std::shared_ptr event_engine) + std::shared_ptr event_engine, + grpc_closure* on_receive_settings) : endpoint_(std::move(endpoint)), outgoing_frames_(kMpscSize), stream_id_mutex_(/*Initial Stream Id*/ 1), bytes_sent_in_last_write_(false), + incoming_header_in_progress_(false), + incoming_header_end_stream_(false), + is_first_write_(true), + incoming_header_stream_id_(0), + on_receive_settings_(on_receive_settings), keepalive_time_(std::max( Duration::Seconds(10), channel_args.GetDurationFromIntMillis(GRPC_ARG_KEEPALIVE_TIME_MS) .value_or(Duration::Infinity()))), + // Keepalive timeout is only passed to the keepalive manager if it is less + // than the ping timeout. As keepalives use pings for health checks, if + // keepalive timeout is greater than ping timeout, we would always hit the + // ping timeout first. + keepalive_timeout_(std::max( + Duration::Zero(), + channel_args.GetDurationFromIntMillis(GRPC_ARG_KEEPALIVE_TIMEOUT_MS) + .value_or(keepalive_time_ == Duration::Infinity() + ? Duration::Infinity() + : (Duration::Seconds(20))))), ping_timeout_(std::max( Duration::Zero(), channel_args.GetDurationFromIntMillis(GRPC_ARG_PING_TIMEOUT_MS) @@ -430,11 +687,16 @@ Http2ClientTransport::Http2ClientTransport( : Duration::Minutes(1)))), ping_manager_(channel_args, PingSystemInterfaceImpl::Make(this), event_engine), + keepalive_manager_( + KeepAliveInterfaceImpl::Make(this), + ((keepalive_timeout_ < ping_timeout_) ? keepalive_timeout_ + : Duration::Infinity()), + keepalive_time_), keepalive_permit_without_calls_(false) { - // TODO(tjagtap) : [PH2][P1] : Save and apply channel_args. - // TODO(tjagtap) : [PH2][P1] : Initialize settings_ to appropriate values. + // TODO(tjagtap) : [PH2][P2] : Save and apply channel_args. + // TODO(tjagtap) : [PH2][P2] : Initialize settings_ to appropriate values. - HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor Begin"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor Begin"; // Initialize the general party and write party. auto general_party_arena = SimpleArenaAllocator(0)->MakeArena(); @@ -445,7 +707,14 @@ Http2ClientTransport::Http2ClientTransport( // TODO(tjagtap) : [PH2][P2] Fix when needed. general_party_->Spawn("WriteLoop", WriteLoop(), OnWriteLoopEnded()); + // The keepalive loop is only spawned if the keepalive time is not infinity. + keepalive_manager_.Spawn(general_party_.get()); + // TODO(tjagtap) : [PH2][P2] Fix Settings workflow. + Http2ErrorCode code = settings_.mutable_local().Apply( + Http2Settings::kInitialWindowSizeWireId, + (Http2Settings::max_initial_window_size() - 1)); + DCHECK(code == Http2ErrorCode::kNoError); std::optional settings_frame = settings_.MaybeSendUpdate(); if (settings_frame.has_value()) { @@ -457,14 +726,126 @@ Http2ClientTransport::Http2ClientTransport( }, [](GRPC_UNUSED absl::Status status) {}); } + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor End"; +} + +// This function MUST be idempotent. +void Http2ClientTransport::CloseStream(uint32_t stream_id, absl::Status status, + CloseStreamArgs args, + DebugLocation whence) { + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseStream for stream id: " + << stream_id << " status=" << status + << " location=" << whence.file() << ":" + << whence.line(); + + // TODO(akshitpatel) : [PH2][P3] : Measure the impact of holding mutex + // throughout this function. + MutexLock lock(&transport_mutex_); + auto pair = stream_list_.find(stream_id); + if (pair == stream_list_.end()) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport::CloseStream for stream id: " << stream_id + << " stream not found"; + return; + } + auto& stream = pair->second; + + if (args.close_reads) { + stream->MarkHalfClosedRemote(); + } + if (args.close_writes) { + stream->MarkHalfClosedLocal(); + } + + if (stream->IsClosed()) { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport::CloseStream for stream id: " << stream_id + << " closing stream."; + if (args.send_rst_stream) { + // TODO(akshitpatel) : [PH2][P2] : Send RST_STREAM frame. + } + + if (args.push_trailing_metadata) { + stream->call.SpawnPushServerTrailingMetadata( + ServerMetadataFromStatus(status)); + } + stream_list_.erase(stream_id); + } +} - HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor End"; +void Http2ClientTransport::CloseTransport() { + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseTransport"; + + // This is the only place where the general_party_ is + // reset. + general_party_.reset(); +} + +void Http2ClientTransport::MaybeSpawnCloseTransport(Http2Status http2_status, + DebugLocation whence) { + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MaybeSpawnCloseTransport " + "status=" + << http2_status << " location=" << whence.file() << ":" + << whence.line(); + + // Free up the stream_list at this point. This would still allow the frames + // in the MPSC to be drained and block any additional frames from being + // enqueued. Additionally this also prevents additional frames with non-zero + // stream_ids from being processed by the read loop. + ReleasableMutexLock lock(&transport_mutex_); + if (is_transport_closed_) { + lock.Release(); + return; + } + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MaybeSpawnCloseTransport " + "Initiating transport close"; + is_transport_closed_ = true; + absl::flat_hash_map> stream_list = + std::move(stream_list_); + stream_list_.clear(); + state_tracker_.SetState(GRPC_CHANNEL_SHUTDOWN, + http2_status.GetAbslConnectionError(), + "transport closed"); + lock.Release(); + + general_party_->Spawn( + "CloseTransport", + [self = RefAsSubclass(), + stream_list = std::move(stream_list), + http2_status = std::move(http2_status)]() mutable { + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport::CloseTransport Cleaning up call stacks"; + // Clean up the call stacks for all active streams. + for (const auto& pair : stream_list) { + // There is no merit in transitioning the stream to + // closed state here as the subsequent lookups would + // fail. Also, as this is running on the transport + // party, there would not be concurrent access to the stream. + auto& stream = pair.second; + stream->call.SpawnPushServerTrailingMetadata( + ServerMetadataFromStatus(http2_status.GetAbslConnectionError())); + } + + // RFC9113 : A GOAWAY frame might not immediately precede closing of + // the connection; a receiver of a GOAWAY that has no more use for the + // connection SHOULD still send a GOAWAY frame before terminating the + // connection. + // TODO(akshitpatel) : [PH2][P2] : There would a timer for sending + // goaway here. Once goaway is sent or timer is expired, close the + // transport. + return Map(Immediate(absl::OkStatus()), + [self](GRPC_UNUSED absl::Status) mutable { + self->CloseTransport(); + return Empty{}; + }); + }, + [](Empty) {}); } Http2ClientTransport::~Http2ClientTransport() { - // TODO(tjagtap) : [PH2][P1] : Implement the needed cleanup - HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor Begin"; - HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor End"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor Begin"; + DCHECK(stream_list_.empty()); + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor End"; } /////////////////////////////////////////////////////////////////////////////// @@ -475,7 +856,7 @@ RefCountedPtr Http2ClientTransport::LookupStream( MutexLock lock(&transport_mutex_); auto it = stream_list_.find(stream_id); if (it == stream_list_.end()) { - HTTP2_CLIENT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::LookupStream Stream not found stream_id=" << stream_id; return nullptr; @@ -486,24 +867,38 @@ RefCountedPtr Http2ClientTransport::LookupStream( bool Http2ClientTransport::MakeStream(CallHandler call_handler, const uint32_t stream_id) { // https://datatracker.ietf.org/doc/html/rfc9113#name-stream-identifiers - // TODO(tjagtap) : [PH2][P0] Validate implementation. + // TODO(tjagtap) : [PH2][P2] Validate implementation. // TODO(akshitpatel) : [PH2][P1] : Probably do not need this lock. This // function is always called under the stream_id_mutex_. The issue is the - // OnDone needs to be synchronous and hence InterActivityMutex might not be an - // option to protect the stream_list_. + // OnDone needs to be synchronous and hence InterActivityMutex might not be + // an option to protect the stream_list_. MutexLock lock(&transport_mutex_); const bool on_done_added = call_handler.OnDone([self = RefAsSubclass(), stream_id](bool cancelled) { - HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get() - << " id=" << stream_id - << " done: cancelled=" << cancelled; + GRPC_HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get() + << " id=" << stream_id + << " done: cancelled=" << cancelled; if (cancelled) { - // TODO(tjagtap) : [PH2][P1] Cancel implementation. + // TODO(akshitpatel) : [PH2][P2] : There are two ways to handle + // cancellation. + // 1. Call CloseStream from the on_done callback as done here. This + // will be invoked when PullServerTrailingMetadata resolves. + // 2. Call CloseStream from the OutboundLoop. When the call is + // cancelled, for_each() should return with an error. The + // WasCancelled() function can be used to determinie if the call + // was cancelled. + // At this point, both the above mentioned approaches seem to be more + // or less the same as both are running on the call party. + self->CloseStream(stream_id, absl::CancelledError(), + CloseStreamArgs{ + /*close_reads=*/true, + /*close_writes=*/true, + /*send_rst_stream=*/true, + /*push_trailing_metadata=*/false, + }); } - MutexLock lock(&self->transport_mutex_); - self->stream_list_.erase(stream_id); }); if (!on_done_added) return false; stream_list_.emplace( @@ -518,23 +913,25 @@ auto Http2ClientTransport::CallOutboundLoop( CallHandler call_handler, const uint32_t stream_id, InterActivityMutex::Lock lock /* Locked stream_id_mutex */, ClientMetadataHandle metadata) { - HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop"; // Convert a message to a Http2DataFrame and send the frame out. - auto send_message = [self = RefAsSubclass(), - stream_id](MessageHandle message) mutable { - // TODO(akshitpatel) : [PH2][P2] : Assuming one message per frame. - // This will eventually change as more logic is added. - SliceBuffer frame_payload; - size_t payload_size = message->payload()->Length(); - AppendGrpcHeaderToSliceBuffer(frame_payload, message->flags(), - payload_size); - frame_payload.TakeAndAppend(*message->payload()); - Http2DataFrame frame{stream_id, /*end_stream*/ false, - std::move(frame_payload)}; - HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop send_message"; - return self->EnqueueOutgoingFrame(std::move(frame)); - }; + auto send_message = + [self = RefAsSubclass(), + stream_id](MessageHandle message) mutable { + // TODO(akshitpatel) : [PH2][P2] : Assuming one message per frame. + // This will eventually change as more logic is added. + SliceBuffer frame_payload; + size_t payload_size = message->payload()->Length(); + AppendGrpcHeaderToSliceBuffer(frame_payload, message->flags(), + payload_size); + frame_payload.TakeAndAppend(*message->payload()); + Http2DataFrame frame{stream_id, /*end_stream*/ false, + std::move(frame_payload)}; + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport CallOutboundLoop send_message"; + return self->EnqueueOutgoingFrame(std::move(frame)); + }; SliceBuffer buf; encoder_.EncodeRawHeaders(*metadata.get(), buf); @@ -543,14 +940,30 @@ auto Http2ClientTransport::CallOutboundLoop( return GRPC_LATENT_SEE_PROMISE( "Ph2CallOutboundLoop", TrySeq( - EnqueueOutgoingFrame(std::move(frame)), + Map(EnqueueOutgoingFrame(std::move(frame)), + [self = RefAsSubclass(), + stream_id](absl::Status status) { + if (status.ok()) { + // TODO(akshitpatel) : [PH2][P3] : Investigate if stream + // lookup can be done once outside the promise and all the + // promises can hold a reference to the stream. + auto stream = self->LookupStream(stream_id); + if (GPR_UNLIKELY(stream == nullptr)) { + LOG(ERROR) + << "Stream not found while sending initial metadata"; + return absl::InternalError( + "Stream not found while sending initial metadata"); + } + stream->SentInitialMetadata(); + } + return status; + }), [call_handler, send_message, lock = std::move(lock)]() { // The lock will be released once the promise is constructed from - // this factory. ForEach will be polled after the lock is released. + // this factory. ForEach will be polled after the lock is + // released. return ForEach(MessagesFrom(call_handler), send_message); }, - // TODO(akshitpatel): [PH2][P2][RISK] : Need to check if it is okay to - // send half close when the call is cancelled. [self = RefAsSubclass(), stream_id]() mutable { // TODO(akshitpatel): [PH2][P2] : Figure out a way to send the end // of stream frame in the same frame as the last message. @@ -559,16 +972,17 @@ auto Http2ClientTransport::CallOutboundLoop( }, [call_handler]() mutable { return Map(call_handler.WasCancelled(), [](bool cancelled) { - HTTP2_CLIENT_DLOG << "Http2ClientTransport PH2CallOutboundLoop" - " End with cancelled=" - << cancelled; + GRPC_HTTP2_CLIENT_DLOG + << "Http2ClientTransport PH2CallOutboundLoop End with " + "cancelled=" + << cancelled; return (cancelled) ? absl::CancelledError() : absl::OkStatus(); }); })); } void Http2ClientTransport::StartCall(CallHandler call_handler) { - HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall Begin"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall Begin"; call_handler.SpawnGuarded( "OutboundLoop", TrySeq( @@ -596,7 +1010,7 @@ void Http2ClientTransport::StartCall(CallHandler call_handler) { }, []() { return absl::InternalError("Failed to make stream"); }); })); - HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall End"; + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall End"; } } // namespace http2 diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.h b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.h index 75e6c63dd59..87059487352 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_client_transport.h @@ -30,13 +30,16 @@ #include "src/core/ext/transport/chttp2/transport/http2_settings.h" #include "src/core/ext/transport/chttp2/transport/http2_status.h" #include "src/core/ext/transport/chttp2/transport/http2_transport.h" +#include "src/core/ext/transport/chttp2/transport/keepalive.h" #include "src/core/ext/transport/chttp2/transport/message_assembler.h" #include "src/core/ext/transport/chttp2/transport/ping_promise.h" #include "src/core/lib/promise/inter_activity_mutex.h" #include "src/core/lib/promise/mpsc.h" #include "src/core/lib/promise/party.h" +#include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/promise_endpoint.h" #include "src/core/lib/transport/transport.h" +#include "src/core/util/orphanable.h" #include "src/core/util/ref_counted_ptr.h" #include "src/core/util/sync.h" @@ -66,8 +69,10 @@ namespace http2 { // |---------------------|--------------|-----------------------|------------| // | Endpoint Read Loop | Infinite | On transport close | One | // | Endpoint Write Loop | Infinite | On transport close | One | +// | Close Transport | CloseTimeout | On transport close | One | // Max Party Slots (Always): 2 +// Max Promise Slots (Worst Case): 3 // Experimental : This is just the initial skeleton of class // and it is functions. The code will be written iteratively. @@ -83,8 +88,13 @@ class Http2ClientTransport final : public ClientTransport { Http2ClientTransport( PromiseEndpoint endpoint, GRPC_UNUSED const ChannelArgs& channel_args, std::shared_ptr - event_engine); + event_engine, + grpc_closure* on_receive_settings); + Http2ClientTransport(const Http2ClientTransport&) = delete; + Http2ClientTransport& operator=(const Http2ClientTransport&) = delete; + Http2ClientTransport(Http2ClientTransport&&) = delete; + Http2ClientTransport& operator=(Http2ClientTransport&&) = delete; ~Http2ClientTransport() override; FilterStackTransport* filter_stack_transport() override { return nullptr; } @@ -101,6 +111,10 @@ class Http2ClientTransport final : public ClientTransport { void StartCall(CallHandler call_handler) override; void PerformOp(grpc_transport_op*) override; + void StartConnectivityWatch( + grpc_connectivity_state state, + OrphanablePtr watcher); + void StopConnectivityWatch(ConnectivityStateWatcherInterface* watcher); void Orphan() override; void AbortWithError(); @@ -110,19 +124,23 @@ class Http2ClientTransport final : public ClientTransport { } auto TestOnlyEnqueueOutgoingFrame(Http2Frame frame) { + // TODO(tjagtap) : [PH2][P3] : See if making a sender in the constructor + // and using that always would be more efficient. return AssertResultType(Map( - outgoing_frames_.MakeSender().Send(std::move(frame)), + outgoing_frames_.MakeSender().Send(std::move(frame), 1), [](StatusFlag status) { - HTTP2_CLIENT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::TestOnlyEnqueueOutgoingFrame status=" << status; return (status.ok()) ? absl::OkStatus() : absl::InternalError("Failed to enqueue frame"); })); } + auto TestOnlySendPing(absl::AnyInvocable on_initiate) { return ping_manager_.RequestPing(std::move(on_initiate)); } + template auto TestOnlySpawnPromise(absl::string_view name, Factory factory) { return general_party_->Spawn(name, std::move(factory), [](auto) {}); @@ -139,6 +157,10 @@ class Http2ClientTransport final : public ClientTransport { Http2Status ProcessHttp2WindowUpdateFrame(Http2WindowUpdateFrame frame); Http2Status ProcessHttp2ContinuationFrame(Http2ContinuationFrame frame); Http2Status ProcessHttp2SecurityFrame(Http2SecurityFrame frame); + Http2Status ProcessMetadata(uint32_t stream_id, HeaderAssembler& assembler, + CallHandler& call, + bool& did_push_initial_metadata, + bool& did_push_trailing_metadata); // Reading from the endpoint. @@ -175,10 +197,12 @@ class Http2ClientTransport final : public ClientTransport { // Returns a promise to enqueue a frame to MPSC auto EnqueueOutgoingFrame(Http2Frame frame) { + // TODO(tjagtap) : [PH2][P3] : See if making a sender in the constructor + // and using that always would be more efficient. return AssertResultType(Map( - outgoing_frames_.MakeSender().Send(std::move(frame)), + outgoing_frames_.MakeSender().Send(std::move(frame), 1), [self = RefAsSubclass()](StatusFlag status) { - HTTP2_CLIENT_DLOG + GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::EnqueueOutgoingFrame status=" << status; return (status.ok()) ? absl::OkStatus() @@ -188,12 +212,14 @@ class Http2ClientTransport final : public ClientTransport { })); } + // Force triggers a transport write cycle + auto TriggerWriteCycle() { return EnqueueOutgoingFrame(Http2EmptyFrame{}); } + RefCountedPtr general_party_; PromiseEndpoint endpoint_; Http2SettingsManager settings_; - // TODO(tjagtap) : [PH2][P3] : This is not nice. Fix by using Stapler. Http2FrameHeader current_frame_header_; // Managing the streams @@ -201,20 +227,95 @@ class Http2ClientTransport final : public ClientTransport { explicit Stream(CallHandler call, const uint32_t stream_id1) : call(std::move(call)), stream_state(HttpStreamState::kIdle), - stream_id(stream_id1) {} + stream_id(stream_id1), + header_assembler(stream_id1), + did_push_initial_metadata(false), + did_push_trailing_metadata(false) {} + + // Modify the stream state + // The possible stream transitions are as follows: + // kIdle -> kOpen + // kOpen -> kClosed/kHalfClosedLocal/kHalfClosedRemote + // kHalfClosedLocal/kHalfClosedRemote -> kClosed + // kClosed -> kClosed + void SentInitialMetadata() { + DCHECK(stream_state == HttpStreamState::kIdle); + stream_state = HttpStreamState::kOpen; + } + + void MarkHalfClosedLocal() { + switch (stream_state) { + case HttpStreamState::kIdle: + DCHECK(false) << "MarkHalfClosedLocal called for an idle stream"; + break; + case HttpStreamState::kOpen: + stream_state = HttpStreamState::kHalfClosedLocal; + break; + case HttpStreamState::kHalfClosedRemote: + stream_state = HttpStreamState::kClosed; + break; + case HttpStreamState::kHalfClosedLocal: + break; + case HttpStreamState::kClosed: + break; + } + } + + void MarkHalfClosedRemote() { + switch (stream_state) { + case HttpStreamState::kIdle: + DCHECK(false) << "MarkHalfClosedRemote called for an idle stream"; + break; + case HttpStreamState::kOpen: + stream_state = HttpStreamState::kHalfClosedRemote; + break; + case HttpStreamState::kHalfClosedLocal: + stream_state = HttpStreamState::kClosed; + break; + case HttpStreamState::kHalfClosedRemote: + break; + case HttpStreamState::kClosed: + break; + } + } + + inline bool IsClosed() const { + return stream_state == HttpStreamState::kClosed; + } CallHandler call; + // TODO(akshitpatel) : [PH2][P3] : Investigate if this needs to be atomic. HttpStreamState stream_state; const uint32_t stream_id; TransportSendQeueue send_queue; GrpcMessageAssembler assembler; HeaderAssembler header_assembler; - // TODO(tjagtap) : [PH2][P2] : Add more members as necessary + // TODO(akshitpatel) : [PH2][P2] : StreamQ should maintain a flag that + // tracks if the half close has been sent for this stream. This flag is used + // to notify the mixer that this stream is closed for + // writes(HalfClosedLocal). When the mixer dequeues the last message for + // the streamQ, it will mark the stream as closed for writes and send a + // frame with end_stream or set the end_stream flag in the last data + // frame being sent out. This is done as the stream state should not + // transition to HalfClosedLocal till the end_stream frame is sent. + bool did_push_initial_metadata; + bool did_push_trailing_metadata; }; uint32_t NextStreamId( InterActivityMutex::Lock& next_stream_id_lock) { const uint32_t stream_id = *next_stream_id_lock; + if (stream_id > RFC9113::kMaxStreamId31Bit) { + // TODO(tjagtap) : [PH2][P3] : Handle case if transport runs out of stream + // ids + // RFC9113 : Stream identifiers cannot be reused. Long-lived connections + // can result in an endpoint exhausting the available range of stream + // identifiers. A client that is unable to establish a new stream + // identifier can establish a new connection for new streams. A server + // that is unable to establish a new stream identifier can send a GOAWAY + // frame so that the client is forced to open a new connection for new + // streams. + } // RFC9113 : Streams initiated by a client MUST use odd-numbered stream // identifiers. (*next_stream_id_lock) += 2; @@ -234,26 +335,62 @@ class Http2ClientTransport final : public ClientTransport { InterActivityMutex stream_id_mutex_; HPackCompressor encoder_; HPackParser parser_; + bool is_transport_closed_ ABSL_GUARDED_BY(transport_mutex_) = false; + + ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(transport_mutex_){ + "http2_client", GRPC_CHANNEL_READY}; bool MakeStream(CallHandler call_handler, uint32_t stream_id); + + struct CloseStreamArgs { + bool close_reads; + bool close_writes; + bool send_rst_stream; + bool push_trailing_metadata; + }; + // This function MUST be idempotent. void CloseStream(uint32_t stream_id, absl::Status status, - DebugLocation whence = {}) { - HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseStream for stream id: " - << stream_id << " status=" << status - << " location=" << whence.file() << ":" << whence.line(); - // TODO(akshitpatel) : [PH2][P1] : Implement this. - } + CloseStreamArgs args, DebugLocation whence = {}); + RefCountedPtr LookupStream(uint32_t stream_id); - // This function MUST be idempotent. - void CloseTransport(const Http2Status& status, DebugLocation whence = {}) { - HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseTransport status=" - << status << " location=" << whence.file() << ":" - << whence.line(); - // TODO(akshitpatel) : [PH2][P1] : Implement this. + auto EndpointReadSlice(const size_t num_bytes) { + return Map(endpoint_.ReadSlice(num_bytes), + [self = RefAsSubclass()]( + absl::StatusOr status) { + // We are ignoring the case where the read fails and call + // GotData() regardless. Reasoning: + // 1. It is expected that if the read fails, the transport will + // close and the keepalive loop will be stopped. + // 2. It does not seem worth to have an extra condition for the + // success cases which would be way more common. + self->keepalive_manager_.GotData(); + return status; + }); + } + + auto EndpointRead(const size_t num_bytes) { + return Map(endpoint_.Read(num_bytes), + [self = RefAsSubclass()]( + absl::StatusOr status) { + // We are ignoring the case where the read fails and call + // GotData() regardless. Reasoning: + // 1. It is expected that if the read fails, the transport will + // close and the keepalive loop will be stopped. + // 2. It does not seem worth to have an extra condition for the + // success cases which would be way more common. + self->keepalive_manager_.GotData(); + return status; + }); } + // This function MUST run on the transport party. + void CloseTransport(); + + void MaybeSpawnCloseTransport(Http2Status http2_status, + DebugLocation whence = {}); + // Handles the error status and returns the corresponding absl status. Absl // Status is returned so that the error can be gracefully handled // by promise primitives. @@ -267,23 +404,45 @@ class Http2ClientTransport final : public ClientTransport { DCHECK(error_type != Http2Status::Http2ErrorType::kOk); if (error_type == Http2Status::Http2ErrorType::kStreamError) { + LOG(ERROR) << "Stream Error: " << status.DebugString(); CloseStream(current_frame_header_.stream_id, status.GetAbslStreamError(), + CloseStreamArgs{ + /*close_reads=*/true, + /*close_writes=*/true, + /*send_rst_stream=*/true, + /*push_trailing_metadata=*/true, + }, whence); return absl::OkStatus(); } else if (error_type == Http2Status::Http2ErrorType::kConnectionError) { - CloseTransport(status, whence); - return status.GetAbslConnectionError(); + LOG(ERROR) << "Connection Error: " << status.DebugString(); + absl::Status absl_status = status.GetAbslConnectionError(); + MaybeSpawnCloseTransport(std::move(status), whence); + return absl_status; } - GPR_UNREACHABLE_CODE(return absl::InternalError("Invalid error type")); } + bool bytes_sent_in_last_write_; + bool incoming_header_in_progress_; + bool incoming_header_end_stream_; + bool is_first_write_; + uint32_t incoming_header_stream_id_; + grpc_closure* on_receive_settings_; // Ping related members - Duration keepalive_time_; - Duration ping_timeout_; + // TODO(akshitpatel) : [PH2][P2] : Consider removing the timeout related + // members. + // Duration between two consecutive keepalive pings + const Duration keepalive_time_; + // Duration to wait for a keepalive ping ack before triggering timeout. This + // only takes effect if the assigned value is less than the ping timeout. + const Duration keepalive_timeout_; + // Duration to wait for ping ack before triggering timeout + const Duration ping_timeout_; PingManager ping_manager_; std::vector pending_ping_acks_; + KeepaliveManager keepalive_manager_; // Flags bool keepalive_permit_without_calls_; @@ -291,6 +450,7 @@ class Http2ClientTransport final : public ClientTransport { auto SendPing(absl::AnyInvocable on_initiate) { return ping_manager_.RequestPing(std::move(on_initiate)); } + auto WaitForPingAck() { return ping_manager_.WaitForPingAck(); } // Ping Helper functions // Returns a promise that resolves once a ping frame is written to the @@ -345,21 +505,26 @@ class Http2ClientTransport final : public ClientTransport { } Promise TriggerWrite() override { - return transport_->EnqueueOutgoingFrame(Http2EmptyFrame{}); + return transport_->TriggerWriteCycle(); } Promise PingTimeout() override { - // TODO(akshitpatel) : [PH2][P1] : Trigger goaway here. + // TODO(akshitpatel) : [PH2][P2] : Trigger goaway here. // Returns a promise that resolves once goaway is sent. LOG(INFO) << "Ping timeout at time: " << Timestamp::Now(); + // TODO(akshitpatel) : [PH2][P2] : The error code here has been chosen + // based on CHTTP2's usage of GRPC_STATUS_UNAVAILABLE (which corresponds + // to kRefusedStream). However looking at RFC9113, definition of + // kRefusedStream doesn't seem to fit this case. We should revisit this + // and update the error code. return Immediate( transport_->HandleError(Http2Status::Http2ConnectionError( Http2ErrorCode::kRefusedStream, "Ping timeout"))); } private: - // TODO(akshitpatel) : [PH2][P1] : Eventually there should be a separate ref + // TODO(akshitpatel) : [PH2][P2] : Eventually there should be a separate ref // counted struct/class passed to all the transport promises/members. This // will help removing back references from the transport members to // transport and greatly simpilfy the cleanup path. @@ -367,6 +532,53 @@ class Http2ClientTransport final : public ClientTransport { explicit PingSystemInterfaceImpl(Http2ClientTransport* transport) : transport_(transport) {} }; + + class KeepAliveInterfaceImpl : public KeepAliveInterface { + public: + static std::unique_ptr Make( + Http2ClientTransport* transport) { + return std::make_unique( + KeepAliveInterfaceImpl(transport)); + } + + private: + explicit KeepAliveInterfaceImpl(Http2ClientTransport* transport) + : transport_(transport) {} + Promise SendPingAndWaitForAck() override { + return TrySeq(transport_->TriggerWriteCycle(), [transport = transport_] { + return transport->WaitForPingAck(); + }); + } + Promise OnKeepAliveTimeout() override { + // TODO(akshitpatel) : [PH2][P2] : Trigger goaway here. + LOG(INFO) << "Keepalive timeout triggered"; + + // TODO(akshitpatel) : [PH2][P2] : The error code here has been chosen + // based on CHTTP2's usage of GRPC_STATUS_UNAVAILABLE (which corresponds + // to kRefusedStream). However looking at RFC9113, definition of + // kRefusedStream doesn't seem to fit this case. We should revisit this + // and update the error code. + return Immediate( + transport_->HandleError(Http2Status::Http2ConnectionError( + Http2ErrorCode::kRefusedStream, "Keepalive timeout"))); + } + + bool NeedToSendKeepAlivePing() override { + bool need_to_send_ping = false; + { + MutexLock lock(&transport_->transport_mutex_); + need_to_send_ping = (transport_->keepalive_permit_without_calls_ || + !transport_->stream_list_.empty()); + } + return need_to_send_ping; + } + + // TODO(akshitpatel) : [PH2][P2] : Eventually there should be a separate ref + // counted struct/class passed to all the transport promises/members. This + // will help removing back references from the transport members to + // transport and greatly simpilfy the cleanup path. + Http2ClientTransport* transport_; + }; }; // Since the corresponding class in CHTTP2 is about 3.9KB, our goal is to diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.cc index b17784544e4..6a3945ba8bd 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.cc @@ -48,8 +48,7 @@ namespace grpc_core { namespace http2 { -// TODO(tjagtap) : [PH2][P1] : Consider moving to common code. -#define HTTP2_SERVER_DLOG \ +#define GRPC_HTTP2_SERVER_DLOG \ DLOG_IF(INFO, GRPC_TRACE_FLAG_ENABLED(http2_ph2_transport)) using grpc_event_engine::experimental::EventEngine; @@ -62,12 +61,12 @@ using grpc_event_engine::experimental::EventEngine; // rollout begins // TODO(akshitpatel) : [PH2][P2] : Choose appropriate size later. -// TODO(tjagtap) : [PH2][P1] : Consider moving to common code. +// TODO(tjagtap) : [PH2][P2] : Consider moving to common code. constexpr int kMpscSize = 10; void Http2ServerTransport::SetCallDestination( RefCountedPtr call_destination) { - // TODO(tjagtap) : [PH2][P1] : Implement this function. + // TODO(tjagtap) : [PH2][P2] : Implement this function. CHECK(call_destination_ == nullptr); CHECK(call_destination != nullptr); call_destination_ = call_destination; @@ -75,30 +74,31 @@ void Http2ServerTransport::SetCallDestination( } void Http2ServerTransport::PerformOp(GRPC_UNUSED grpc_transport_op*) { - HTTP2_SERVER_DLOG << "Http2ServerTransport PerformOp Begin"; - // TODO(tjagtap) : [PH2][P1] : Implement this function. - HTTP2_SERVER_DLOG << "Http2ServerTransport PerformOp End"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport PerformOp Begin"; + // TODO(tjagtap) : [PH2][P2] : Implement this function. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport PerformOp End"; } void Http2ServerTransport::Orphan() { - HTTP2_SERVER_DLOG << "Http2ServerTransport Orphan Begin"; - // TODO(tjagtap) : [PH2][P1] : Implement the needed cleanup + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport Orphan Begin"; + // TODO(tjagtap) : [PH2][P2] : Implement the needed cleanup general_party_.reset(); Unref(); - HTTP2_SERVER_DLOG << "Http2ServerTransport Orphan End"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport Orphan End"; } void Http2ServerTransport::AbortWithError() { - HTTP2_SERVER_DLOG << "Http2ServerTransport AbortWithError Begin"; - // TODO(tjagtap) : [PH2][P1] : Implement this function. - HTTP2_SERVER_DLOG << "Http2ServerTransport AbortWithError End"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport AbortWithError Begin"; + // TODO(tjagtap) : [PH2][P2] : Implement this function. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport AbortWithError End"; } Http2Status ProcessHttp2DataFrame(Http2DataFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-data - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2DataFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ProcessHttp2DataFrame Factory"; + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2DataFrame Promise { stream_id=" << frame.stream_id << ", end_stream=" << frame.end_stream << ", payload=" << frame.payload.JoinIntoString() << "}"; @@ -107,9 +107,10 @@ Http2Status ProcessHttp2DataFrame(Http2DataFrame frame) { Http2Status ProcessHttp2HeaderFrame(Http2HeaderFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-headers - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2HeaderFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ProcessHttp2HeaderFrame Factory"; + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2HeaderFrame Promise { stream_id=" << frame.stream_id << ", end_headers=" << frame.end_headers << ", end_stream=" << frame.end_stream @@ -119,10 +120,10 @@ Http2Status ProcessHttp2HeaderFrame(Http2HeaderFrame frame) { Http2Status ProcessHttp2RstStreamFrame(Http2RstStreamFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-rst_stream - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2RstStreamFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2RstStreamFrame Promise{ stream_id=" << frame.stream_id << ", error_code=" << frame.error_code << " }"; return Http2Status::Ok(); @@ -130,11 +131,12 @@ Http2Status ProcessHttp2RstStreamFrame(Http2RstStreamFrame frame) { Http2Status ProcessHttp2SettingsFrame(Http2SettingsFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-settings - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2SettingsFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ProcessHttp2SettingsFrame Factory"; + // TODO(tjagtap) : [PH2][P2] : Implement this. // Load into this.settings_ // Take necessary actions as per settings that have changed. - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2SettingsFrame Promise { ack=" << frame.ack << ", settings length=" << frame.settings.size() << "}"; return Http2Status::Ok(); @@ -142,9 +144,10 @@ Http2Status ProcessHttp2SettingsFrame(Http2SettingsFrame frame) { Http2Status ProcessHttp2PingFrame(Http2PingFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-ping - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2PingFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ProcessHttp2PingFrame Factory"; + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2PingFrame Promise { ack=" << frame.ack << ", opaque=" << frame.opaque << " }"; return Http2Status::Ok(); @@ -152,23 +155,23 @@ Http2Status ProcessHttp2PingFrame(Http2PingFrame frame) { Http2Status ProcessHttp2GoawayFrame(Http2GoawayFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-goaway - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2GoawayFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2GoawayFrame Promise { " - "last_stream_id=" - << frame.last_stream_id - << ", error_code=" << frame.error_code - << ", debug_data=" << frame.debug_data.as_string_view() - << "}"; + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ProcessHttp2GoawayFrame Factory"; + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ProcessHttp2GoawayFrame Promise { " + "last_stream_id=" + << frame.last_stream_id << ", error_code=" << frame.error_code + << ", debug_data=" << frame.debug_data.as_string_view() << "}"; return Http2Status::Ok(); } Http2Status ProcessHttp2WindowUpdateFrame(Http2WindowUpdateFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-window_update - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2WindowUpdateFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2WindowUpdateFrame Promise { " " stream_id=" << frame.stream_id << ", increment=" << frame.increment << "}"; @@ -177,10 +180,10 @@ Http2Status ProcessHttp2WindowUpdateFrame(Http2WindowUpdateFrame frame) { Http2Status ProcessHttp2ContinuationFrame(Http2ContinuationFrame frame) { // https://www.rfc-editor.org/rfc/rfc9113.html#name-continuation - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2ContinuationFrame Factory"; - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2ContinuationFrame Promise { " "stream_id=" << frame.stream_id << ", end_headers=" << frame.end_headers @@ -189,17 +192,17 @@ Http2Status ProcessHttp2ContinuationFrame(Http2ContinuationFrame frame) { } Http2Status ProcessHttp2SecurityFrame(Http2SecurityFrame frame) { - // TODO(tjagtap) : [PH2][P2] : This is not in the RFC. Understand usage. - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2SecurityFrame Factory"; + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ProcessHttp2SecurityFrame Factory"; // TODO(tjagtap) : [PH2][P2] : Implement this. - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessHttp2SecurityFrame Promise { payload=" << frame.payload.JoinIntoString() << " }"; return Http2Status::Ok(); } auto Http2ServerTransport::ProcessOneFrame(Http2Frame frame) { - HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessOneFrame Factory"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ProcessOneFrame Factory"; return AssertResultType(MatchPromise( std::move(frame), [](Http2DataFrame frame) { @@ -240,29 +243,30 @@ auto Http2ServerTransport::ProcessOneFrame(Http2Frame frame) { } auto Http2ServerTransport::ReadAndProcessOneFrame() { - HTTP2_SERVER_DLOG << "Http2ServerTransport ReadAndProcessOneFrame Factory"; + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ReadAndProcessOneFrame Factory"; return AssertResultType(TrySeq( // Fetch the first kFrameHeaderSize bytes of the Frame, these contain // the frame header. endpoint_.ReadSlice(kFrameHeaderSize), // Parse the frame header. [](Slice header_bytes) -> Http2FrameHeader { - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ReadAndProcessOneFrame Parse " << header_bytes.as_string_view(); return Http2FrameHeader::Parse(header_bytes.begin()); }, // Read the payload of the frame. [this](Http2FrameHeader header) { - // TODO(tjagtap) : [PH2][P3] : This is not nice. Fix by using Stapler. - HTTP2_SERVER_DLOG << "Http2ServerTransport ReadAndProcessOneFrame Read"; + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport ReadAndProcessOneFrame Read"; current_frame_header_ = header; return AssertResultType>( endpoint_.Read(header.length)); }, // Parse the payload of the frame based on frame type. [this](SliceBuffer payload) -> absl::StatusOr { - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ReadAndProcessOneFrame ParseFramePayload " << payload.JoinIntoString(); ValueOrHttp2Status frame = @@ -275,7 +279,7 @@ auto Http2ServerTransport::ReadAndProcessOneFrame() { ValueOrHttp2Status::TakeStatus(std::move(frame))); }, [this](GRPC_UNUSED Http2Frame frame) { - HTTP2_SERVER_DLOG + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ReadAndProcessOneFrame ProcessOneFrame"; return Map( ProcessOneFrame(std::move(frame)), @@ -289,67 +293,70 @@ auto Http2ServerTransport::ReadAndProcessOneFrame() { } auto Http2ServerTransport::ReadLoop() { - HTTP2_SERVER_DLOG << "Http2ServerTransport ReadLoop Factory"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ReadLoop Factory"; return AssertResultType(Loop([this]() { return TrySeq(ReadAndProcessOneFrame(), []() -> LoopCtl { - HTTP2_SERVER_DLOG << "Http2ServerTransport ReadLoop Continue"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport ReadLoop Continue"; return Continue(); }); })); } auto Http2ServerTransport::OnReadLoopEnded() { - HTTP2_SERVER_DLOG << "Http2ServerTransport OnReadLoopEnded Factory"; - return [self = RefAsSubclass()](absl::Status status) { - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG << "Http2ServerTransport OnReadLoopEnded Promise Status=" - << status; - GRPC_UNUSED absl::Status error_status = - self->HandleError(Http2Status::AbslConnectionError( - status.code(), std::string(status.message()))); - }; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport OnReadLoopEnded Factory"; + return + [self = RefAsSubclass()](absl::Status status) { + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport OnReadLoopEnded Promise Status=" << status; + GRPC_UNUSED absl::Status error_status = + self->HandleError(Http2Status::AbslConnectionError( + status.code(), std::string(status.message()))); + }; } auto Http2ServerTransport::WriteFromQueue() { - HTTP2_SERVER_DLOG << "Http2ServerTransport WriteFromQueue Factory"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport WriteFromQueue Factory"; return []() -> Poll { - // TODO(tjagtap) : [PH2][P1] : Implement this. + // TODO(tjagtap) : [PH2][P2] : Implement this. // Read from the mpsc queue and write it to endpoint - HTTP2_SERVER_DLOG << "Http2ServerTransport WriteFromQueue Promise"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport WriteFromQueue Promise"; return Pending{}; }; } auto Http2ServerTransport::WriteLoop() { - HTTP2_SERVER_DLOG << "Http2ServerTransport WriteLoop Factory"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport WriteLoop Factory"; return AssertResultType(Loop([this]() { return TrySeq(WriteFromQueue(), []() -> LoopCtl { - HTTP2_SERVER_DLOG << "Http2ServerTransport WriteLoop Continue"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport WriteLoop Continue"; return Continue(); }); })); } auto Http2ServerTransport::OnWriteLoopEnded() { - HTTP2_SERVER_DLOG << "Http2ServerTransport OnWriteLoopEnded Factory"; - return [self = RefAsSubclass()](absl::Status status) { - // TODO(tjagtap) : [PH2][P1] : Implement this. - HTTP2_SERVER_DLOG << "Http2ServerTransport OnWriteLoopEnded Promise Status=" - << status; - GRPC_UNUSED absl::Status error_status = - self->HandleError(Http2Status::AbslConnectionError( - status.code(), std::string(status.message()))); - }; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport OnWriteLoopEnded Factory"; + return + [self = RefAsSubclass()](absl::Status status) { + // TODO(tjagtap) : [PH2][P2] : Implement this. + GRPC_HTTP2_SERVER_DLOG + << "Http2ServerTransport OnWriteLoopEnded Promise Status=" + << status; + GRPC_UNUSED absl::Status error_status = + self->HandleError(Http2Status::AbslConnectionError( + status.code(), std::string(status.message()))); + }; } Http2ServerTransport::Http2ServerTransport( PromiseEndpoint endpoint, GRPC_UNUSED const ChannelArgs& channel_args, std::shared_ptr event_engine) : endpoint_(std::move(endpoint)), outgoing_frames_(kMpscSize) { - // TODO(tjagtap) : [PH2][P1] : Save and apply channel_args. - // TODO(tjagtap) : [PH2][P1] : Initialize settings_ to appropriate values. + // TODO(tjagtap) : [PH2][P2] : Save and apply channel_args. + // TODO(tjagtap) : [PH2][P2] : Initialize settings_ to appropriate values. - HTTP2_SERVER_DLOG << "Http2ServerTransport Constructor Begin"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport Constructor Begin"; // Initialize the general party and write party. auto general_party_arena = SimpleArenaAllocator(0)->MakeArena(); @@ -358,14 +365,14 @@ Http2ServerTransport::Http2ServerTransport( general_party_->Spawn("ReadLoop", ReadLoop(), OnReadLoopEnded()); general_party_->Spawn("WriteLoop", WriteLoop(), OnWriteLoopEnded()); - HTTP2_SERVER_DLOG << "Http2ServerTransport Constructor End"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport Constructor End"; } Http2ServerTransport::~Http2ServerTransport() { - // TODO(tjagtap) : [PH2][P1] : Implement the needed cleanup - HTTP2_SERVER_DLOG << "Http2ServerTransport Destructor Begin"; + // TODO(tjagtap) : [PH2][P2] : Implement the needed cleanup + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport Destructor Begin"; general_party_.reset(); - HTTP2_SERVER_DLOG << "Http2ServerTransport Destructor End"; + GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport Destructor End"; } } // namespace http2 diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.h b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.h index f2f397a3fbf..c5903ce1755 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_server_transport.h @@ -110,7 +110,6 @@ class Http2ServerTransport final : public ServerTransport { PromiseEndpoint endpoint_; Http2SettingsManager settings_; - // TODO(tjagtap) : [PH2][P3] : This is not nice. Fix by using Stapler. Http2FrameHeader current_frame_header_; struct Stream : public RefCounted { @@ -137,14 +136,14 @@ class Http2ServerTransport final : public ServerTransport { LOG(INFO) << "Http2ServerTransport::CloseStream for stream id=" << stream_id << " status=" << status << " location=" << whence.file() << ":" << whence.line(); - // TODO(akshitpatel) : [PH2][P1] : Implement this. + // TODO(akshitpatel) : [PH2][P2] : Implement this. } // This function is supposed to be idempotent. void CloseTransport(const Http2Status& status, DebugLocation whence = {}) { LOG(INFO) << "Http2ClientTransport::CloseTransport status=" << status << " location=" << whence.file() << ":" << whence.line(); - // TODO(akshitpatel) : [PH2][P1] : Implement this. + // TODO(akshitpatel) : [PH2][P2] : Implement this. } // Handles the error status and returns the corresponding absl status. Absl @@ -171,15 +170,15 @@ class Http2ServerTransport final : public ServerTransport { GPR_UNREACHABLE_CODE(return absl::InternalError("Invalid error type")); } - // TODO(tjagtap) : [PH2][P1] : Either use this in code or delete it. + // TODO(tjagtap) : [PH2][P2] : Either use this in code or delete it. // uint32_t next_stream_id_ ABSL_GUARDED_BY(transport_mutex_) = 1; - // TODO(tjagtap) : [PH2][P1] : Either use this in code or delete it. This was + // TODO(tjagtap) : [PH2][P2] : Either use this in code or delete it. This was // copied from Chaotic Good. // uint32_t last_seen_new_stream_id_ = 0; - // TODO(tjagtap) : [PH2][P1] : Implement if needed. + // TODO(tjagtap) : [PH2][P2] : Implement if needed. // uint32_t MakeStream(CallHandler call_handler); - // TODO(tjagtap) : [PH2][P1] : Implement if needed. + // TODO(tjagtap) : [PH2][P2] : Implement if needed. // RefCountedPtr LookupStream(uint32_t // stream_id); }; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_settings.h b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_settings.h index 96b7fa580a5..725cb332e96 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_settings.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_settings.h @@ -25,9 +25,9 @@ #include "absl/functional/function_ref.h" #include "absl/strings/string_view.h" +#include "src/core/channelz/property_list.h" #include "src/core/ext/transport/chttp2/transport/frame.h" #include "src/core/ext/transport/chttp2/transport/http2_status.h" -#include "src/core/util/json/json.h" #include "src/core/util/useful.h" namespace grpc_core { @@ -133,20 +133,18 @@ class Http2Settings { bool operator!=(const Http2Settings& rhs) const { return !operator==(rhs); } - Json::Object ToJsonObject() const { - Json::Object object; - object["headerTableSize"] = Json::FromNumber(header_table_size()); - object["maxConcurrentStreams"] = Json::FromNumber(max_concurrent_streams()); - object["initialWindowSize"] = Json::FromNumber(initial_window_size()); - object["maxFrameSize"] = Json::FromNumber(max_frame_size()); - object["maxHeaderListSize"] = Json::FromNumber(max_header_list_size()); - object["preferredReceiveCryptoMessageSize"] = - Json::FromNumber(preferred_receive_crypto_message_size()); - object["enablePush"] = Json::FromBool(enable_push()); - object["allowTrueBinaryMetadata"] = - Json::FromBool(allow_true_binary_metadata()); - object["allowSecurityFrame"] = Json::FromBool(allow_security_frame()); - return object; + channelz::PropertyList ChannelzProperties() const { + return channelz::PropertyList() + .Set(header_table_size_name(), header_table_size()) + .Set(max_concurrent_streams_name(), max_concurrent_streams()) + .Set(initial_window_size_name(), initial_window_size()) + .Set(max_frame_size_name(), max_frame_size()) + .Set(max_header_list_size_name(), max_header_list_size()) + .Set(preferred_receive_crypto_message_size_name(), + preferred_receive_crypto_message_size()) + .Set(enable_push_name(), enable_push()) + .Set(allow_true_binary_metadata_name(), allow_true_binary_metadata()) + .Set(allow_security_frame_name(), allow_security_frame()); } private: @@ -169,13 +167,12 @@ class Http2SettingsManager { Http2Settings& mutable_peer() { return peer_; } const Http2Settings& peer() const { return peer_; } - Json::Object ToJsonObject() const { - Json::Object object; - object["local"] = Json::FromObject(local_.ToJsonObject()); - object["sent"] = Json::FromObject(sent_.ToJsonObject()); - object["peer"] = Json::FromObject(peer_.ToJsonObject()); - object["acked"] = Json::FromObject(acked_.ToJsonObject()); - return object; + channelz::PropertyGrid ChannelzProperties() const { + return channelz::PropertyGrid() + .SetColumn("local", local_.ChannelzProperties()) + .SetColumn("sent", sent_.ChannelzProperties()) + .SetColumn("peer", peer_.ChannelzProperties()) + .SetColumn("acked", acked_.ChannelzProperties()); } std::optional MaybeSendUpdate(); diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.cc new file mode 100644 index 00000000000..0161f404a9a --- /dev/null +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.cc @@ -0,0 +1,30 @@ +// +// +// Copyright 2025 gRPC authors. +// +// 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. +// +// + +#include "src/core/ext/transport/chttp2/transport/http2_stats_collector.h" + +#include + +namespace grpc_core { + +std::shared_ptr CreateHttp2StatsCollector( + grpc_auth_context* /*ctx*/) { + return std::make_shared(); +} + +} // namespace grpc_core diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.h b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.h new file mode 100644 index 00000000000..1125a748b79 --- /dev/null +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_stats_collector.h @@ -0,0 +1,33 @@ +// +// +// Copyright 2025 gRPC authors. +// +// 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. +// +// + +#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_STATS_COLLECTOR_H +#define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_STATS_COLLECTOR_H + +#include + +#include "src/core/telemetry/stats_data.h" + +namespace grpc_core { + +std::shared_ptr CreateHttp2StatsCollector( + grpc_auth_context* ctx); + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_STATS_COLLECTOR_H diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_status.h b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_status.h index 0466fedf12c..5d185819d95 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_status.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_status.h @@ -51,6 +51,7 @@ enum class Http2ErrorCode : uint8_t { kConnectError = 0xa, kEnhanceYourCalm = 0xb, kInadequateSecurity = 0xc, + kHTTP11Required = 0xd, kDoNotUse = 0xffu // Force use of a default clause }; @@ -75,6 +76,10 @@ inline absl::StatusCode ErrorCodeToAbslStatusCode( GPR_UNREACHABLE_CODE(return absl::StatusCode::kUnknown); } +inline uint8_t GetMaxHttp2ErrorCode() { + return static_cast(Http2ErrorCode::kHTTP11Required); +} + inline Http2ErrorCode AbslStatusCodeToErrorCode(const absl::StatusCode status) { switch (status) { case absl::StatusCode::kOk: @@ -323,7 +328,7 @@ class GRPC_MUST_USE_RESULT Http2Status { }; // We can add more methods and helpers as needed. -// This class is similar to ValueOrFailure but a more minamilasit version. +// This class is similar to ValueOrFailure but a more minimalist version. // Reference : // https://github.com/grpc/grpc/blob/master/src/core/lib/promise/status_flag.h diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_transport.h b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_transport.h index dd3df4d774e..92e7a2a78e6 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_transport.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_transport.h @@ -42,13 +42,7 @@ namespace http2 { // TODO(tjagtap) : [PH2][P3] : Update the experimental status of the code before // http2 rollout begins. -#define HTTP2_TRANSPORT_DLOG \ - DLOG_IF(INFO, GRPC_TRACE_FLAG_ENABLED(http2_ph2_transport)) - -#define HTTP2_CLIENT_DLOG \ - DLOG_IF(INFO, GRPC_TRACE_FLAG_ENABLED(http2_ph2_transport)) - -#define HTTP2_SERVER_DLOG \ +#define GRPC_HTTP2_CLIENT_DLOG \ DLOG_IF(INFO, GRPC_TRACE_FLAG_ENABLED(http2_ph2_transport)) // TODO(akshitpatel) : [PH2][P2] : Choose appropriate size later. diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h index f38baf788cc..e9256b7d3b7 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h @@ -43,8 +43,6 @@ struct H2DataTrace { bool end_stream; uint32_t payload_length; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = Json::FromString("DATA"); @@ -62,8 +60,6 @@ struct H2HeaderTrace { bool continuation; uint32_t payload_length; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = continuation ? Json::FromString("CONTINUATION") @@ -80,8 +76,6 @@ struct H2RstStreamTrace { uint32_t stream_id; uint32_t error_code; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = Json::FromString("RST_STREAM"); @@ -95,11 +89,6 @@ struct H2SettingsTrace { bool ack; std::vector settings; - size_t MemoryUsage() const { - return sizeof(*this) + - sizeof(Http2SettingsFrame::Setting) * settings.size(); - } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = Json::FromString("SETTINGS"); @@ -120,8 +109,6 @@ struct H2PingTrace { bool ack; uint64_t opaque; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = Json::FromString("PING"); @@ -136,8 +123,6 @@ struct H2GoAwayTrace { uint32_t error_code; std::string debug_data; - size_t MemoryUsage() const { return sizeof(*this) + debug_data.size(); } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = Json::FromString("GOAWAY"); @@ -152,8 +137,6 @@ struct H2WindowUpdateTrace { uint32_t stream_id; uint32_t window_size_increment; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = Json::FromString("WINDOW_UPDATE"); @@ -166,8 +149,6 @@ template struct H2SecurityTrace { uint32_t payload_length; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["read"] = Json::FromBool(kRead); json["frame_type"] = Json::FromString("SECURITY"); @@ -181,8 +162,6 @@ struct H2UnknownFrameTrace { uint32_t stream_id; uint32_t payload_length; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["frame_type"] = Json::FromString("UNKNOWN"); json["type"] = Json::FromNumber(type); @@ -197,8 +176,6 @@ struct H2FlowControlStall { int64_t stream_window; uint32_t stream_id; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["metadata_type"] = Json::FromString("FLOW_CONTROL_STALL"); json["transport_window"] = Json::FromNumber(transport_window); @@ -210,8 +187,6 @@ struct H2FlowControlStall { struct H2BeginWriteCycle { uint32_t target_size; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["metadata_type"] = Json::FromString("BEGIN_WRITE_CYCLE"); json["target_size"] = Json::FromNumber(target_size); @@ -221,8 +196,6 @@ struct H2BeginWriteCycle { struct H2BeginEndpointWrite { uint32_t write_size; - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["metadata_type"] = Json::FromString("BEGIN_ENDPOINT_WRITE"); json["write_size"] = Json::FromNumber(write_size); @@ -230,8 +203,6 @@ struct H2BeginEndpointWrite { }; struct H2EndWriteCycle { - size_t MemoryUsage() const { return sizeof(*this); } - void RenderJson(Json::Object& json) const { json["metadata_type"] = Json::FromString("END_WRITE_CYCLE"); } diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/internal.h b/deps/grpc/src/core/ext/transport/chttp2/transport/internal.h index b88abee3669..3e894f7a07a 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/internal.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/internal.h @@ -57,6 +57,7 @@ #include "src/core/ext/transport/chttp2/transport/ping_abuse_policy.h" #include "src/core/ext/transport/chttp2/transport/ping_callbacks.h" #include "src/core/ext/transport/chttp2/transport/ping_rate_policy.h" +#include "src/core/ext/transport/chttp2/transport/transport_common.h" #include "src/core/ext/transport/chttp2/transport/write_size_policy.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" @@ -76,6 +77,7 @@ #include "src/core/telemetry/call_tracer.h" #include "src/core/telemetry/context_list_entry.h" #include "src/core/telemetry/stats.h" +#include "src/core/telemetry/tcp_tracer.h" #include "src/core/util/bitset.h" #include "src/core/util/debug_location.h" #include "src/core/util/ref_counted.h" @@ -236,10 +238,12 @@ struct grpc_chttp2_transport final : public grpc_core::FilterStackTransport, public: explicit ChannelzDataSource(grpc_chttp2_transport* transport) : grpc_core::channelz::DataSource(transport->channelz_socket), - transport_(transport) {} - ~ChannelzDataSource() { ResetDataSource(); } + transport_(transport) { + SourceConstructed(); + } + ~ChannelzDataSource() { SourceDestructing(); } - void AddData(grpc_core::channelz::DataSink& sink) override; + void AddData(grpc_core::channelz::DataSink sink) override; std::unique_ptr GetZTrace( absl::string_view name) override; @@ -283,6 +287,9 @@ struct grpc_chttp2_transport final : public grpc_core::FilterStackTransport, void WriteSecurityFrame(grpc_core::SliceBuffer* data); void WriteSecurityFrameLocked(grpc_core::SliceBuffer* data); + // We depend on the ep being available for the life of the transport in + // at least one place - event callback in WriteEventSink. Hence, this should + // only be orphaned in the destructor. grpc_core::OrphanablePtr ep; grpc_core::Mutex ep_destroy_mu; // Guards endpoint destruction only. @@ -581,7 +588,7 @@ struct grpc_chttp2_transport final : public grpc_core::FilterStackTransport, grpc_core::Timestamp last_window_update_time = grpc_core::Timestamp::InfPast(); - grpc_core::Http2StatsCollector http2_stats; + std::shared_ptr http2_stats; grpc_core::Http2ZTraceCollector http2_ztrace_collector; GPR_NO_UNIQUE_ADDRESS grpc_core::latent_see::Flow write_flow; @@ -759,6 +766,11 @@ struct grpc_chttp2_stream { void grpc_chttp2_initiate_write(grpc_chttp2_transport* t, grpc_chttp2_initiate_write_reason reason); +struct TcpCallTracerWithOffset { + std::shared_ptr tcp_call_tracer; + size_t byte_offset; +}; + struct grpc_chttp2_begin_write_result { /// are we writing? bool writing; @@ -766,6 +778,8 @@ struct grpc_chttp2_begin_write_result { bool partial; /// did we queue any completions as part of beginning the write bool early_results_scheduled; + /// Tcp Call Tracers if any + std::vector tcp_call_tracers; }; grpc_chttp2_begin_write_result grpc_chttp2_begin_write( grpc_chttp2_transport* t); @@ -822,10 +836,6 @@ void grpc_chttp2_settings_timeout( #define GRPC_HEADER_SIZE_IN_BYTES 5 #define MAX_SIZE_T (~(size_t)0) -#define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" -#define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \ - (sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1) - #define GRPC_CHTTP2_IF_TRACING(severity) \ LOG_IF(severity, GRPC_TRACE_FLAG_ENABLED(http)) diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.cc index 5fff3775a5f..c852b9d0092 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.cc @@ -28,10 +28,10 @@ namespace grpc_core { namespace http2 { KeepaliveManager::KeepaliveManager( std::unique_ptr keep_alive_interface, - Duration keepalive_timeout, Duration keepalive_interval) + Duration keepalive_timeout, const Duration keepalive_time) : keep_alive_interface_(std::move(keep_alive_interface)), keepalive_timeout_(keepalive_timeout), - keepalive_interval_(keepalive_interval) {} + keepalive_time_(keepalive_time) {} auto KeepaliveManager::WaitForKeepAliveTimeout() { return AssertResultType( @@ -39,13 +39,15 @@ auto KeepaliveManager::WaitForKeepAliveTimeout() { return If( data_received_in_last_cycle_, [] { - KEEPALIVE_LOG << "Keepalive timeout triggered but " - << "received data. Resolving with ok status"; + GRPC_HTTP2_KEEPALIVE_LOG + << "Keepalive timeout triggered but " + << "received data. Resolving with ok status"; return Immediate(absl::OkStatus()); }, [this] { - KEEPALIVE_LOG << "Keepalive timeout triggered and no " - "data received. Triggering keepalive timeout."; + GRPC_HTTP2_KEEPALIVE_LOG + << "Keepalive timeout triggered and no " + "data received. Triggering keepalive timeout."; // Once the keepalive timeout is triggered, ensure that // WaitForData() is never resolved. This is needed as the // keepalive loop should break once the timeout is triggered. @@ -64,7 +66,7 @@ auto KeepaliveManager::TimeoutAndSendPing() { SendPingAndWaitForAck()); } auto KeepaliveManager::MaybeSendKeepAlivePing() { - LOG(INFO) << "KeepaliveManager::MaybeSendKeepAlivePing"; + GRPC_HTTP2_KEEPALIVE_LOG << "KeepaliveManager::MaybeSendKeepAlivePing"; return AssertResultType( TrySeq(If( NeedToSendKeepAlivePing(), @@ -82,14 +84,21 @@ auto KeepaliveManager::MaybeSendKeepAlivePing() { } void KeepaliveManager::Spawn(Party* party) { + if (!IsKeepAliveNeeded()) { + GRPC_HTTP2_KEEPALIVE_LOG << "Not spawning keepalive loop."; + return; + } + keep_alive_spawned_ = true; + party->Spawn("KeepAliveLoop", Loop([this]() { return TrySeq( - Sleep(keepalive_interval_), + Sleep(keepalive_time_), [this]() { return MaybeSendKeepAlivePing(); }, []() -> LoopCtl { return Continue(); }); }), [](auto status) { - LOG(INFO) << "KeepAlive end with status: " << status; + GRPC_HTTP2_KEEPALIVE_LOG << "KeepAlive end with status: " + << status; }); } } // namespace http2 diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.h b/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.h index de3d24c97c1..c56638dfbad 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/keepalive.h @@ -25,7 +25,7 @@ namespace grpc_core { namespace http2 { -#define KEEPALIVE_LOG VLOG(2) +#define GRPC_HTTP2_KEEPALIVE_LOG VLOG(2) class KeepAliveInterface { public: @@ -44,17 +44,20 @@ class KeepAliveInterface { class KeepaliveManager { public: KeepaliveManager(std::unique_ptr keep_alive_interface, - Duration keepalive_timeout, Duration keepalive_interval); + Duration keepalive_timeout, Duration keepalive_time); + + // Spawns the keepalive loop on the given party. This MUST be called at most + // once during the lifetime of the keepalive manager. void Spawn(Party* party); // Needs to be called when any data is read from the endpoint. void GotData() { if (keep_alive_timeout_triggered_) { - KEEPALIVE_LOG + GRPC_HTTP2_KEEPALIVE_LOG << "KeepAlive timeout triggered. Not setting data_received_ to true"; return; } - KEEPALIVE_LOG << "Data received. Setting data_received_ to true"; + GRPC_HTTP2_KEEPALIVE_LOG << "Data received. Setting data_received_ to true"; data_received_in_last_cycle_ = true; auto waker = std::move(waker_); // This will only trigger a wakeup if WaitForData() is pending on this @@ -90,10 +93,11 @@ class KeepaliveManager { auto WaitForData() { return [this]() -> Poll { if (data_received_in_last_cycle_) { - KEEPALIVE_LOG << "WaitForData: Data received. Poll resolved"; + GRPC_HTTP2_KEEPALIVE_LOG << "WaitForData: Data received. Poll resolved"; return absl::OkStatus(); } else { - KEEPALIVE_LOG << "WaitForData: Data not received. Poll pending"; + GRPC_HTTP2_KEEPALIVE_LOG + << "WaitForData: Data not received. Poll pending"; waker_ = GetContext()->MakeNonOwningWaker(); return Pending{}; } @@ -104,22 +108,27 @@ class KeepaliveManager { return keep_alive_interface_->SendPingAndWaitForAck(); } - // If no data is received in the last keepalive_interval, we should send a + // If no data is received in the last keepalive_time, we should send a // keepalive ping. This also means that there can be scenarios where we would - // send one keepalive ping in ~(2*keepalive_interval). + // send one keepalive ping in ~(2*keepalive_time). bool NeedToSendKeepAlivePing() { return (!data_received_in_last_cycle_) && (keep_alive_interface_->NeedToSendKeepAlivePing()); } + bool IsKeepAliveNeeded() { + return (keepalive_time_ != Duration::Infinity() && !keep_alive_spawned_); + } + std::unique_ptr keep_alive_interface_; // If the keepalive_timeout_ is set to infinity, then the timeout is dictated // by the ping timeout. Otherwise, this field can be used to set a specific // timeout for keepalive pings. Duration keepalive_timeout_; - Duration keepalive_interval_; + const Duration keepalive_time_; bool data_received_in_last_cycle_ = false; bool keep_alive_timeout_triggered_ = false; + bool keep_alive_spawned_ = false; Waker waker_; }; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/message_assembler.h b/deps/grpc/src/core/ext/transport/chttp2/transport/message_assembler.h index 24f49a2bf3b..cc4af0c54d7 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/message_assembler.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/message_assembler.h @@ -51,8 +51,8 @@ class GrpcMessageAssembler { public: // Input : The input must contain the payload from the Http2DataFrame. // This function will move the payload into an internal buffer. - absl::Status AppendNewDataFrame(SliceBuffer& payload, - const bool is_end_stream) { + Http2Status AppendNewDataFrame(SliceBuffer& payload, + const bool is_end_stream) { DCHECK(!is_end_stream_) << "Calling this function when a previous frame was marked as the last " "frame does not make sense."; @@ -60,31 +60,31 @@ class GrpcMessageAssembler { if constexpr (sizeof(size_t) == 4) { if (GPR_UNLIKELY(message_buffer_.Length() >= UINT32_MAX - payload.Length())) { - // STREAM_ERROR - return absl::Status( - absl::StatusCode::kInternal, + return Http2Status::Http2StreamError( + Http2ErrorCode::kInternalError, "Stream Error: SliceBuffer overflow for 32 bit platforms."); } } payload.MoveFirstNBytesIntoSliceBuffer(payload.Length(), message_buffer_); DCHECK_EQ(payload.Length(), 0u); - return absl::OkStatus(); + return Http2Status::Ok(); } // Returns a valid MessageHandle if it has a complete message. // Returns a nullptr if it does not have a complete message. // Returns an error if an incomplete message is received and the stream ends. - absl::StatusOr ExtractMessage() { + ValueOrHttp2Status ExtractMessage() { const size_t current_len = message_buffer_.Length(); if (current_len < kGrpcHeaderSizeInBytes) { + // TODO(tjagtap) : [PH2][P3] : Write a test for this failure. + LOG(ERROR) << "Incomplete gRPC message received"; return ReturnNullOrError(); } GrpcMessageHeader header = ExtractGrpcHeader(message_buffer_); if constexpr (sizeof(size_t) == 4) { if (GPR_UNLIKELY(header.length > kOneGb)) { - // STREAM_ERROR - return absl::Status( - absl::StatusCode::kInternal, + return Http2Status::Http2StreamError( + Http2ErrorCode::kInternalError, "Stream Error: SliceBuffer overflow for 32 bit platforms."); } } @@ -102,18 +102,18 @@ class GrpcMessageAssembler { header.length, *(grpc_message->payload())); uint32_t& flag = grpc_message->mutable_flags(); flag = header.flags; - return grpc_message; + return std::move(grpc_message); } return ReturnNullOrError(); } private: - absl::StatusOr ReturnNullOrError() { - // TODO(tjagtap) : [PH2][P1] Replace with Http2StatusOr when that PR lands + ValueOrHttp2Status ReturnNullOrError() { if (GPR_UNLIKELY(is_end_stream_ && message_buffer_.Length() > 0)) { - return absl::InternalError("Incomplete gRPC frame received"); + return Http2Status::Http2StreamError(Http2ErrorCode::kInternalError, + "Incomplete gRPC frame received"); } - return nullptr; + return ValueOrHttp2Status(nullptr); } bool is_end_stream_ = false; SliceBuffer message_buffer_; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/parsing.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/parsing.cc index 105420a6726..491ecf24b3b 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/parsing.cc @@ -545,8 +545,7 @@ void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t) { static grpc_error_handle init_data_frame_parser(grpc_chttp2_transport* t) { // Update BDP accounting since we have received a data frame. grpc_core::BdpEstimator* bdp_est = t->flow_control.bdp_estimator(); - grpc_core::global_stats().IncrementHttp2ReadDataFrameSize( - t->incoming_frame_size); + t->http2_stats->IncrementHttp2ReadDataFrameSize(t->incoming_frame_size); if (bdp_est) { if (t->bdp_ping_blocked) { t->bdp_ping_blocked = false; @@ -671,8 +670,7 @@ static grpc_error_handle init_header_frame_parser(grpc_chttp2_transport* t, nullptr, &t->http2_ztrace_collector)); grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM); return init_header_skip_frame_parser(t, priority_type, is_eoh); - } else if (grpc_core::IsRqFastRejectEnabled() && - GPR_UNLIKELY(t->memory_owner.IsMemoryPressureHigh())) { + } else if (GPR_UNLIKELY(t->memory_owner.IsMemoryPressureHigh())) { // We have more streams allocated than we'd like, so apply some pushback // by refusing this stream. grpc_core::global_stats().IncrementRqCallsRejected(); diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_callbacks.h b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_callbacks.h index bfc6efb6bd9..e04bb6de09e 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_callbacks.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_callbacks.h @@ -28,6 +28,7 @@ #include "absl/functional/any_invocable.h" #include "absl/hash/hash.h" #include "absl/random/bit_gen_ref.h" +#include "src/core/channelz/property_list.h" #include "src/core/lib/debug/trace.h" #include "src/core/util/time.h" @@ -90,6 +91,24 @@ class Chttp2PingCallbacks { grpc_event_engine::experimental::EventEngine* event_engine, Callback callback); + channelz::PropertyList ChannelzProperties() const { + return channelz::PropertyList() + .Set("ping_requested", ping_requested_) + .Set("most_recent_inflight", most_recent_inflight_) + .Set("started_new_ping_without_setting_timeout", + started_new_ping_without_setting_timeout_) + .Set("inflight", + [this]() { + channelz::PropertyTable inflight; + for (const auto& [id, ping] : inflight_) { + inflight.AppendRow(channelz::PropertyList().Set("id", id)); + } + return inflight; + }()) + .Set("num_on_start", on_start_.size()) + .Set("num_on_ack", on_ack_.size()); + } + private: using CallbackVec = std::vector; struct InflightPing { diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.cc index c9bffcc6457..df5f7687a92 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.cc @@ -33,7 +33,7 @@ using SendPingArgs = ::grpc_core::http2::PingInterface::SendPingArgs; using Callback = absl::AnyInvocable; using grpc_event_engine::experimental::EventEngine; -#define PING_LOG \ +#define GRPC_HTTP2_PING_LOG \ LOG_IF(INFO, (GRPC_TRACE_FLAG_ENABLED(http) || \ GRPC_TRACE_FLAG_ENABLED(bdp_estimator) || \ GRPC_TRACE_FLAG_ENABLED(http_keepalive) || \ @@ -90,22 +90,24 @@ bool PingManager::NeedToPing(Duration next_allowed_ping_interval) { ping_callbacks_.CountPingInflight()), [this](Chttp2PingRatePolicy::SendGranted) { // TODO(akshitpatel) : [PH2][P1] : Update some keepalive flags. - PING_LOG << "CLIENT" << "[" << "PH2" - << "]: Ping sent" << ping_rate_policy_.GetDebugString(); + GRPC_HTTP2_PING_LOG << "CLIENT" << "[" << "PH2" + << "]: Ping sent" + << ping_rate_policy_.GetDebugString(); return true; }, [this](Chttp2PingRatePolicy::TooManyRecentPings) { - PING_LOG << "CLIENT" << "[" << "PH2" - << "]: Ping delayed too many recent pings: " - << ping_rate_policy_.GetDebugString(); + GRPC_HTTP2_PING_LOG << "CLIENT" << "[" << "PH2" + << "]: Ping delayed too many recent pings: " + << ping_rate_policy_.GetDebugString(); return false; }, [this](Chttp2PingRatePolicy::TooSoon too_soon) mutable { - PING_LOG << "]: Ping delayed not enough time elapsed since last " - "ping. Last ping:" - << too_soon.last_ping - << ", minimum wait:" << too_soon.next_allowed_ping_interval - << ", need to wait:" << too_soon.wait; + GRPC_HTTP2_PING_LOG + << "]: Ping delayed not enough time elapsed since last " + "ping. Last ping:" + << too_soon.last_ping + << ", minimum wait:" << too_soon.next_allowed_ping_interval + << ", need to wait:" << too_soon.wait; TriggerDelayedPing(too_soon.wait); return false; }); diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.h b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.h index 6ca1c18abd5..820954ffa5a 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_promise.h @@ -62,8 +62,6 @@ class PingInterface { // in any fashion. uint64_t opaque_data = 0; }; - // TODO(tjagtap) : [PH2][P1] Change the return type of the promises to - // Promise type when that is submitted. // Returns a promise that creates and sends a ping frame to the peer. virtual Promise SendPing(SendPingArgs args) = 0; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc index 6d3e66b17cf..25e72e1f638 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc @@ -79,15 +79,11 @@ Chttp2PingRatePolicy::RequestSendPing(Duration next_allowed_ping_interval, // Throttle pings to 1 minute if we haven't sent any data recently if (max_pings_without_data_sent_ != 0 && pings_before_data_sending_required_ == 0) { - if (IsMaxPingsWoDataThrottleEnabled()) { - const Timestamp next_allowed_ping = - last_ping_sent_time_ + kThrottleIntervalWithoutDataSent; - if (next_allowed_ping > now) { - return TooSoon{kThrottleIntervalWithoutDataSent, last_ping_sent_time_, - next_allowed_ping - now}; - } - } else { - return TooManyRecentPings{}; + const Timestamp next_allowed_ping = + last_ping_sent_time_ + kThrottleIntervalWithoutDataSent; + if (next_allowed_ping > now) { + return TooSoon{kThrottleIntervalWithoutDataSent, last_ping_sent_time_, + next_allowed_ping - now}; } } diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.h b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.h index da2b8181763..3bd66366b87 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/ping_rate_policy.h @@ -22,7 +22,9 @@ #include #include +#include "src/core/channelz/property_list.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/util/string.h" #include "src/core/util/time.h" namespace grpc_core { @@ -78,6 +80,15 @@ class Chttp2PingRatePolicy { return max_pings_without_data_sent_; } + channelz::PropertyList ChannelzProperties() const { + return channelz::PropertyList() + .Set("max_pings_without_data_sent", max_pings_without_data_sent_) + .Set("max_inflight_pings", max_inflight_pings_) + .Set("pings_before_data_sending_required", + pings_before_data_sending_required_) + .Set("last_ping_sent_time", last_ping_sent_time_); + } + private: const int max_pings_without_data_sent_; const int max_inflight_pings_; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/stream_data_queue.h b/deps/grpc/src/core/ext/transport/chttp2/transport/stream_data_queue.h index e6383c34e22..e3af898cab7 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/stream_data_queue.h +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/stream_data_queue.h @@ -38,7 +38,7 @@ class StreamDataQueue { StreamDataQueue& operator=(const StreamDataQueue&) = delete; private: - // TODO(akshitpatel) : [PH2][P1] Keep this either in the transport or here. + // TODO(akshitpatel) : [PH2][P2] Keep this either in the transport or here. // Not both places. GrpcMessageDisassembler disassembler; }; diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/stream_lists.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/stream_lists.cc index 20d848c35bb..4ff249fa870 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/stream_lists.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/stream_lists.cc @@ -128,6 +128,26 @@ static void stream_list_add_tail(grpc_chttp2_transport* t, << "]: add to " << stream_list_id_string(id); } +static void stream_list_add_head(grpc_chttp2_transport* t, + grpc_chttp2_stream* s, + grpc_chttp2_stream_list_id id) { + grpc_chttp2_stream* old_head; + CHECK(!s->included.is_set(id)); + old_head = t->lists[id].head; + s->links[id].next = old_head; + s->links[id].prev = nullptr; + if (old_head) { + old_head->links[id].prev = s; + } else { + t->lists[id].tail = s; + } + t->lists[id].head = s; + s->included.set(id); + GRPC_TRACE_LOG(http2_stream_state, INFO) + << t << "[" << s->id << "][" << (t->is_client ? "cli" : "svr") + << "]: add to " << stream_list_id_string(id); +} + static bool stream_list_add(grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_chttp2_stream_list_id id) { if (s->included.is_set(id)) { @@ -137,11 +157,24 @@ static bool stream_list_add(grpc_chttp2_transport* t, grpc_chttp2_stream* s, return true; } +static bool stream_list_prepend(grpc_chttp2_transport* t, grpc_chttp2_stream* s, + grpc_chttp2_stream_list_id id) { + if (s->included.is_set(id)) { + return false; + } + stream_list_add_head(t, s, id); + return true; +} + // wrappers for specializations bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s) { CHECK_NE(s->id, 0u); + if (grpc_core::IsPrioritizeFinishedRequestsEnabled() && + s->send_trailing_metadata != nullptr) { + return stream_list_prepend(t, s, GRPC_CHTTP2_LIST_WRITABLE); + } return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITABLE); } @@ -186,7 +219,12 @@ void grpc_chttp2_list_remove_waiting_for_concurrency(grpc_chttp2_transport* t, void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport* t, grpc_chttp2_stream* s) { - stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); + if (grpc_core::IsPrioritizeFinishedRequestsEnabled() && + s->send_trailing_metadata != nullptr) { + stream_list_prepend(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); + } else { + stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); + } } bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport* t, diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.cc new file mode 100644 index 00000000000..2da491c8d4a --- /dev/null +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.cc @@ -0,0 +1,19 @@ +// +// +// Copyright 2025 gRPC authors. +// +// 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. +// +// + +namespace grpc_core {} // namespace grpc_core \ No newline at end of file diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.h b/deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.h new file mode 100644 index 00000000000..4098dd41da3 --- /dev/null +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/transport_common.h @@ -0,0 +1,27 @@ +// +// +// Copyright 2025 gRPC authors. +// +// 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. +// +// + +#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TRANSPORT_COMMON_H +#define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TRANSPORT_COMMON_H + +// For an HTTP2 connection, this must be sent before the settings frame is sent. +#define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" +#define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \ + (sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1) + +#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TRANSPORT_COMMON_H diff --git a/deps/grpc/src/core/ext/transport/chttp2/transport/writing.cc b/deps/grpc/src/core/ext/transport/chttp2/transport/writing.cc index 77ebe88fffd..5768bc043b5 100644 --- a/deps/grpc/src/core/ext/transport/chttp2/transport/writing.cc +++ b/deps/grpc/src/core/ext/transport/chttp2/transport/writing.cc @@ -58,6 +58,7 @@ #include "src/core/lib/experiments/experiments.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/event_engine_shims/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice.h" #include "src/core/lib/slice/slice_buffer.h" @@ -67,6 +68,7 @@ #include "src/core/telemetry/context_list_entry.h" #include "src/core/telemetry/stats.h" #include "src/core/telemetry/stats_data.h" +#include "src/core/telemetry/tcp_tracer.h" #include "src/core/util/match.h" #include "src/core/util/ref_counted.h" #include "src/core/util/ref_counted_ptr.h" @@ -137,7 +139,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { if (t->channelz_socket != nullptr) { t->channelz_socket->RecordKeepaliveSent(); } - grpc_core::global_stats().IncrementHttp2PingsSent(); + t->http2_stats->IncrementHttp2PingsSent(); if (GRPC_TRACE_FLAG_ENABLED(http) || GRPC_TRACE_FLAG_ENABLED(bdp_estimator) || GRPC_TRACE_FLAG_ENABLED(http_keepalive) || @@ -258,8 +260,8 @@ namespace { class WriteContext { public: explicit WriteContext(grpc_chttp2_transport* t) : t_(t) { - t->http2_stats.IncrementHttp2WritesBegun(); - t->http2_stats.IncrementHttp2WriteTargetSize(target_write_size_); + t->http2_stats->IncrementHttp2WritesBegun(); + t->http2_stats->IncrementHttp2WriteTargetSize(target_write_size_); } void FlushSettings() { @@ -283,7 +285,7 @@ class WriteContext { }); } t_->flow_control.FlushedSettings(); - grpc_core::global_stats().IncrementHttp2SettingsWrites(); + t_->http2_stats->IncrementHttp2SettingsWrites(); } } @@ -339,9 +341,19 @@ class WriteContext { } grpc_chttp2_stream* NextStream() { - if (t_->outbuf.c_slice_buffer()->length > target_write_size_) { - result_.partial = true; - return nullptr; + if (grpc_core::IsChttp2BoundWriteSizeEnabled()) { + if (t_->outbuf.c_slice_buffer()->length >= target_write_size_) { + result_.partial = true; + return nullptr; + } + } else { + // TODO(ctiller): this is likely buggy now, but everything seems to be + // working, so I'm keeping the above fix just for the experiment until + // we've had time to soak it fully. + if (t_->outbuf.c_slice_buffer()->length > target_write_size_) { + result_.partial = true; + return nullptr; + } } grpc_chttp2_stream* s; @@ -361,6 +373,13 @@ class WriteContext { grpc_chttp2_transport* transport() const { return t_; } + void AddTcpCallTracer( + std::shared_ptr tcp_call_tracer, + size_t byte_offset) { + result_.tcp_call_tracers.push_back( + {std::move(tcp_call_tracer), byte_offset}); + } + grpc_chttp2_begin_write_result Result() { result_.writing = t_->outbuf.c_slice_buffer()->count > 0; return result_; @@ -378,7 +397,7 @@ class WriteContext { int initial_metadata_writes_ = 0; int trailing_metadata_writes_ = 0; int message_writes_ = 0; - grpc_chttp2_begin_write_result result_ = {false, false, false}; + grpc_chttp2_begin_write_result result_ = {false, false, false, {}}; }; class DataSendContext { @@ -535,14 +554,14 @@ class StreamWriteContext { t_->http2_ztrace_collector.Append(grpc_core::H2FlowControlStall{ t_->flow_control.remote_window(), data_send_context.stream_remote_window(), s_->id}); - grpc_core::global_stats().IncrementHttp2TransportStalls(); + t_->http2_stats->IncrementHttp2TransportStalls(); report_stall(t_, s_, "transport"); grpc_chttp2_list_add_stalled_by_transport(t_, s_); } else if (data_send_context.stream_remote_window() <= 0) { t_->http2_ztrace_collector.Append(grpc_core::H2FlowControlStall{ t_->flow_control.remote_window(), data_send_context.stream_remote_window(), s_->id}); - grpc_core::global_stats().IncrementHttp2StreamStalls(); + t_->http2_stats->IncrementHttp2StreamStalls(); report_stall(t_, s_, "stream"); grpc_chttp2_list_add_stalled_by_stream(t_, s_); } else if (grpc_core::IsChttp2BoundWriteSizeEnabled()) { @@ -711,9 +730,16 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( grpc_core::GrpcHttp2GetCopyContextFn(); if (copy_context_fn != nullptr && grpc_core::GrpcHttp2GetWriteTimestampsCallback() != nullptr) { + // Old way of collecting TCP traces t->context_list->emplace_back( copy_context_fn(s->arena), outbuf_relative_start_pos, - num_stream_bytes, s->byte_counter, s->write_counter - 1, nullptr); + num_stream_bytes, s->byte_counter, s->write_counter - 1); + } else if (s->call_tracer != nullptr && + grpc_event_engine::experimental:: + grpc_is_event_engine_endpoint(t->ep.get())) { + // New way of collecting TCP traces + ctx.AddTcpCallTracer(s->call_tracer->StartNewTcpTrace(), + s->byte_counter); } } outbuf_relative_start_pos += num_stream_bytes; diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h new file mode 100644 index 00000000000..8e90d50d4c8 --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h @@ -0,0 +1,571 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/channelz.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPB_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPB_H_ + +#include "upb/generated_code_support.h" + +#include "src/proto/grpc/channelz/v2/channelz.upb_minitable.h" + +#include "google/protobuf/any.upb_minitable.h" +#include "google/protobuf/timestamp.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct grpc_channelz_v2_Data { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Data; +typedef struct grpc_channelz_v2_Entity { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Entity; +typedef struct grpc_channelz_v2_TraceEvent { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_TraceEvent; +struct google_protobuf_Any; +struct google_protobuf_Timestamp; + + + +/* grpc.channelz.v2.Data */ + +UPB_INLINE grpc_channelz_v2_Data* grpc_channelz_v2_Data_new(upb_Arena* arena) { + return (grpc_channelz_v2_Data*)_upb_Message_New(&grpc__channelz__v2__Data_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Data* grpc_channelz_v2_Data_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Data* ret = grpc_channelz_v2_Data_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Data_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Data* grpc_channelz_v2_Data_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Data* ret = grpc_channelz_v2_Data_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Data_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Data_serialize(const grpc_channelz_v2_Data* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Data_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Data_serialize_ex(const grpc_channelz_v2_Data* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Data_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Data_clear_name(grpc_channelz_v2_Data* msg) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Data_name(const grpc_channelz_v2_Data* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Data_clear_value(grpc_channelz_v2_Data* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const struct google_protobuf_Any* grpc_channelz_v2_Data_value(const grpc_channelz_v2_Data* msg) { + const struct google_protobuf_Any* default_val = NULL; + const struct google_protobuf_Any* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Any_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Data_has_value(const grpc_channelz_v2_Data* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void grpc_channelz_v2_Data_set_name(grpc_channelz_v2_Data *msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Data_set_value(grpc_channelz_v2_Data *msg, struct google_protobuf_Any* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Any_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_Any* grpc_channelz_v2_Data_mutable_value(grpc_channelz_v2_Data* msg, upb_Arena* arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)grpc_channelz_v2_Data_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)_upb_Message_New(&google__protobuf__Any_msg_init, arena); + if (sub) grpc_channelz_v2_Data_set_value(msg, sub); + } + return sub; +} + +/* grpc.channelz.v2.Entity */ + +UPB_INLINE grpc_channelz_v2_Entity* grpc_channelz_v2_Entity_new(upb_Arena* arena) { + return (grpc_channelz_v2_Entity*)_upb_Message_New(&grpc__channelz__v2__Entity_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Entity* grpc_channelz_v2_Entity_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Entity* ret = grpc_channelz_v2_Entity_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Entity_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Entity* grpc_channelz_v2_Entity_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Entity* ret = grpc_channelz_v2_Entity_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Entity_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Entity_serialize(const grpc_channelz_v2_Entity* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Entity_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Entity_serialize_ex(const grpc_channelz_v2_Entity* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Entity_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Entity_clear_id(grpc_channelz_v2_Entity* msg) { + const upb_MiniTableField field = {1, 32, 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int64_t grpc_channelz_v2_Entity_id(const grpc_channelz_v2_Entity* msg) { + int64_t default_val = (int64_t)0ll; + int64_t ret; + const upb_MiniTableField field = {1, 32, 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Entity_clear_kind(grpc_channelz_v2_Entity* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Entity_kind(const grpc_channelz_v2_Entity* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(24, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Entity_clear_parents(grpc_channelz_v2_Entity* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int64_t const* grpc_channelz_v2_Entity_parents(const grpc_channelz_v2_Entity* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int64_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_Entity_parents_upb_array(const grpc_channelz_v2_Entity* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_Entity_parents_mutable_upb_array(grpc_channelz_v2_Entity* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void grpc_channelz_v2_Entity_clear_orphaned(grpc_channelz_v2_Entity* msg) { + const upb_MiniTableField field = {4, 8, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool grpc_channelz_v2_Entity_orphaned(const grpc_channelz_v2_Entity* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {4, 8, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Entity_clear_timed_out(grpc_channelz_v2_Entity* msg) { + const upb_MiniTableField field = {5, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool grpc_channelz_v2_Entity_timed_out(const grpc_channelz_v2_Entity* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {5, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Entity_clear_data(grpc_channelz_v2_Entity* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Data* const* grpc_channelz_v2_Entity_data(const grpc_channelz_v2_Entity* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_Data* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_Entity_data_upb_array(const grpc_channelz_v2_Entity* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_Entity_data_mutable_upb_array(grpc_channelz_v2_Entity* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void grpc_channelz_v2_Entity_clear_trace(grpc_channelz_v2_Entity* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_TraceEvent* const* grpc_channelz_v2_Entity_trace(const grpc_channelz_v2_Entity* msg, size_t* size) { + const upb_MiniTableField field = {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__TraceEvent_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_TraceEvent* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_Entity_trace_upb_array(const grpc_channelz_v2_Entity* msg, size_t* size) { + const upb_MiniTableField field = {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__TraceEvent_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_Entity_trace_mutable_upb_array(grpc_channelz_v2_Entity* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__TraceEvent_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void grpc_channelz_v2_Entity_set_id(grpc_channelz_v2_Entity *msg, int64_t value) { + const upb_MiniTableField field = {1, 32, 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Entity_set_kind(grpc_channelz_v2_Entity *msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE int64_t* grpc_channelz_v2_Entity_mutable_parents(grpc_channelz_v2_Entity* msg, size_t* size) { + upb_MiniTableField field = {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int64_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE int64_t* grpc_channelz_v2_Entity_resize_parents(grpc_channelz_v2_Entity* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int64_t*)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE bool grpc_channelz_v2_Entity_add_parents(grpc_channelz_v2_Entity* msg, int64_t val, upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void grpc_channelz_v2_Entity_set_orphaned(grpc_channelz_v2_Entity *msg, bool value) { + const upb_MiniTableField field = {4, 8, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Entity_set_timed_out(grpc_channelz_v2_Entity *msg, bool value) { + const upb_MiniTableField field = {5, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE grpc_channelz_v2_Data** grpc_channelz_v2_Entity_mutable_data(grpc_channelz_v2_Entity* msg, size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_Data**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_Data** grpc_channelz_v2_Entity_resize_data(grpc_channelz_v2_Entity* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_Data**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_Data* grpc_channelz_v2_Entity_add_data(grpc_channelz_v2_Entity* msg, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_Data* sub = (struct grpc_channelz_v2_Data*)_upb_Message_New(&grpc__channelz__v2__Data_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE grpc_channelz_v2_TraceEvent** grpc_channelz_v2_Entity_mutable_trace(grpc_channelz_v2_Entity* msg, size_t* size) { + upb_MiniTableField field = {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__TraceEvent_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_TraceEvent**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_TraceEvent** grpc_channelz_v2_Entity_resize_trace(grpc_channelz_v2_Entity* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_TraceEvent**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_TraceEvent* grpc_channelz_v2_Entity_add_trace(grpc_channelz_v2_Entity* msg, upb_Arena* arena) { + upb_MiniTableField field = {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__TraceEvent_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_TraceEvent* sub = (struct grpc_channelz_v2_TraceEvent*)_upb_Message_New(&grpc__channelz__v2__TraceEvent_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.TraceEvent */ + +UPB_INLINE grpc_channelz_v2_TraceEvent* grpc_channelz_v2_TraceEvent_new(upb_Arena* arena) { + return (grpc_channelz_v2_TraceEvent*)_upb_Message_New(&grpc__channelz__v2__TraceEvent_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_TraceEvent* grpc_channelz_v2_TraceEvent_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_TraceEvent* ret = grpc_channelz_v2_TraceEvent_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__TraceEvent_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_TraceEvent* grpc_channelz_v2_TraceEvent_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_TraceEvent* ret = grpc_channelz_v2_TraceEvent_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__TraceEvent_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_TraceEvent_serialize(const grpc_channelz_v2_TraceEvent* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__TraceEvent_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_TraceEvent_serialize_ex(const grpc_channelz_v2_TraceEvent* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__TraceEvent_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_TraceEvent_clear_description(grpc_channelz_v2_TraceEvent* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_TraceEvent_description(const grpc_channelz_v2_TraceEvent* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_TraceEvent_clear_timestamp(grpc_channelz_v2_TraceEvent* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const struct google_protobuf_Timestamp* grpc_channelz_v2_TraceEvent_timestamp(const grpc_channelz_v2_TraceEvent* msg) { + const struct google_protobuf_Timestamp* default_val = NULL; + const struct google_protobuf_Timestamp* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Timestamp_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_TraceEvent_has_timestamp(const grpc_channelz_v2_TraceEvent* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_TraceEvent_clear_data(grpc_channelz_v2_TraceEvent* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Data* const* grpc_channelz_v2_TraceEvent_data(const grpc_channelz_v2_TraceEvent* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_Data* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_TraceEvent_data_upb_array(const grpc_channelz_v2_TraceEvent* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_TraceEvent_data_mutable_upb_array(grpc_channelz_v2_TraceEvent* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void grpc_channelz_v2_TraceEvent_set_description(grpc_channelz_v2_TraceEvent *msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_TraceEvent_set_timestamp(grpc_channelz_v2_TraceEvent *msg, struct google_protobuf_Timestamp* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Timestamp_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_Timestamp* grpc_channelz_v2_TraceEvent_mutable_timestamp(grpc_channelz_v2_TraceEvent* msg, upb_Arena* arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)grpc_channelz_v2_TraceEvent_timestamp(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)_upb_Message_New(&google__protobuf__Timestamp_msg_init, arena); + if (sub) grpc_channelz_v2_TraceEvent_set_timestamp(msg, sub); + } + return sub; +} +UPB_INLINE grpc_channelz_v2_Data** grpc_channelz_v2_TraceEvent_mutable_data(grpc_channelz_v2_TraceEvent* msg, size_t* size) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_Data**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_Data** grpc_channelz_v2_TraceEvent_resize_data(grpc_channelz_v2_TraceEvent* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_Data**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_Data* grpc_channelz_v2_TraceEvent_add_data(grpc_channelz_v2_TraceEvent* msg, upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Data_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_Data* sub = (struct grpc_channelz_v2_Data*)_upb_Message_New(&grpc__channelz__v2__Data_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPB_H_ */ diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c new file mode 100644 index 00000000000..1b332e6ff4c --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c @@ -0,0 +1,120 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/channelz.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#include +#include "upb/generated_code_support.h" +#include "src/proto/grpc/channelz/v2/channelz.upb_minitable.h" +#include "google/protobuf/any.upb_minitable.h" +#include "google/protobuf/timestamp.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_StaticallyTreeShaken); +static const upb_MiniTableSubInternal grpc_channelz_v2_Data__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &google__protobuf__Any_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Data__fields[2] = { + {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Data_msg_init = { + &grpc_channelz_v2_Data__submsgs[0], + &grpc_channelz_v2_Data__fields[0], + UPB_SIZE(24, 40), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Data", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f00000a, &upb_pss_1bt}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Data_msg_init_ptr = &grpc__channelz__v2__Data_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Entity__submsgs[2] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Data_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__TraceEvent_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Entity__fields[7] = { + {1, 32, 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(24, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 40), 0, kUpb_NoSub, 3, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, 8, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {5, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(16, 48), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(20, 56), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Entity_msg_init = { + &grpc_channelz_v2_Entity__submsgs[0], + &grpc_channelz_v2_Entity__fields[0], + UPB_SIZE(40, 64), 7, kUpb_ExtMode_NonExtendable, 7, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Entity", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002000003f000008, &upb_psv8_1bt}, + {0x001000003f000012, &upb_pss_1bt}, + {0x002800003f00001a, &upb_ppv8_1bt}, + {0x000800003f000020, &upb_psb1_1bt}, + {0x000900003f000028, &upb_psb1_1bt}, + {0x003000003f000032, &upb_prm_1bt_max64b}, + {0x003800003f01003a, &upb_prm_1bt_max64b}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Entity_msg_init_ptr = &grpc__channelz__v2__Entity_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_TraceEvent__submsgs[2] = { + {.UPB_PRIVATE(submsg) = &google__protobuf__Timestamp_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Data_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_TraceEvent__fields[3] = { + {1, UPB_SIZE(20, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 40), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__TraceEvent_msg_init = { + &grpc_channelz_v2_TraceEvent__submsgs[0], + &grpc_channelz_v2_TraceEvent__fields[0], + UPB_SIZE(32, 48), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.TraceEvent", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f00000a, &upb_pss_1bt}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002800003f01001a, &upb_prm_1bt_max64b}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__TraceEvent_msg_init_ptr = &grpc__channelz__v2__TraceEvent_msg_init; +static const upb_MiniTable *messages_layout[3] = { + &grpc__channelz__v2__Data_msg_init, + &grpc__channelz__v2__Entity_msg_init, + &grpc__channelz__v2__TraceEvent_msg_init, +}; + +const upb_MiniTableFile src_proto_grpc_channelz_v2_channelz_proto_upb_file_layout = { + messages_layout, + NULL, + NULL, + 3, + 0, + 0, +}; + +#include "upb/port/undef.inc" + diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h new file mode 100644 index 00000000000..d3d70af694f --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h @@ -0,0 +1,36 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/channelz.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPB_MINITABLE_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPB_MINITABLE_H_ + +#include "upb/generated_code_support.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable grpc__channelz__v2__Data_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Data_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Entity_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Entity_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__TraceEvent_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__TraceEvent_msg_init_ptr; + +extern const upb_MiniTableFile src_proto_grpc_channelz_v2_channelz_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPB_MINITABLE_H_ */ diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h new file mode 100644 index 00000000000..aeb252f14e5 --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h @@ -0,0 +1,1272 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/promise.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPB_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPB_H_ + +#include "upb/generated_code_support.h" + +#include "src/proto/grpc/channelz/v2/promise.upb_minitable.h" + +#include "src/proto/grpc/channelz/v2/property_list.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct grpc_channelz_v2_Promise { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise; +typedef struct grpc_channelz_v2_Promise_Custom { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_Custom; +typedef struct grpc_channelz_v2_Promise_If { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_If; +typedef struct grpc_channelz_v2_Promise_Loop { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_Loop; +typedef struct grpc_channelz_v2_Promise_Race { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_Race; +typedef struct grpc_channelz_v2_Promise_SeqStep { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_SeqStep; +typedef struct grpc_channelz_v2_Promise_Seq { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_Seq; +typedef struct grpc_channelz_v2_Promise_JoinBranch { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_JoinBranch; +typedef struct grpc_channelz_v2_Promise_Join { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_Join; +typedef struct grpc_channelz_v2_Promise_Map { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_Promise_Map; +struct grpc_channelz_v2_PropertyList; + +typedef enum { + grpc_channelz_v2_Promise_UNKNOWN = 0, + grpc_channelz_v2_Promise_NORMAL = 1, + grpc_channelz_v2_Promise_TRY = 2 +} grpc_channelz_v2_Promise_CompositionKind; + + + +/* grpc.channelz.v2.Promise */ + +UPB_INLINE grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise*)_upb_Message_New(&grpc__channelz__v2__Promise_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise* ret = grpc_channelz_v2_Promise_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise* ret = grpc_channelz_v2_Promise_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_serialize(const grpc_channelz_v2_Promise* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_serialize_ex(const grpc_channelz_v2_Promise* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise_msg_init, options, arena, &ptr, len); + return ptr; +} +typedef enum { + grpc_channelz_v2_Promise_promise_custom_promise = 1, + grpc_channelz_v2_Promise_promise_unknown_promise = 2, + grpc_channelz_v2_Promise_promise_if_promise = 3, + grpc_channelz_v2_Promise_promise_loop_promise = 4, + grpc_channelz_v2_Promise_promise_race_promise = 5, + grpc_channelz_v2_Promise_promise_seq_promise = 6, + grpc_channelz_v2_Promise_promise_join_promise = 7, + grpc_channelz_v2_Promise_promise_map_promise = 8, + grpc_channelz_v2_Promise_promise_NOT_SET = 0 +} grpc_channelz_v2_Promise_promise_oneofcases; +UPB_INLINE grpc_channelz_v2_Promise_promise_oneofcases grpc_channelz_v2_Promise_promise_case(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_Promise_promise_oneofcases)upb_Message_WhichOneofFieldNumber( + UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearOneof(UPB_UPCAST(msg), &grpc__channelz__v2__Promise_msg_init, &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_custom_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_Custom* grpc_channelz_v2_Promise_custom_promise(const grpc_channelz_v2_Promise* msg) { + const grpc_channelz_v2_Promise_Custom* default_val = NULL; + const grpc_channelz_v2_Promise_Custom* ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Custom_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_custom_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_unknown_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_unknown_promise(const grpc_channelz_v2_Promise* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_unknown_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_if_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 16), -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_If* grpc_channelz_v2_Promise_if_promise(const grpc_channelz_v2_Promise* msg) { + const grpc_channelz_v2_Promise_If* default_val = NULL; + const grpc_channelz_v2_Promise_If* ret; + const upb_MiniTableField field = {3, UPB_SIZE(12, 16), -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__If_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_if_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 16), -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_loop_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 16), -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_Loop* grpc_channelz_v2_Promise_loop_promise(const grpc_channelz_v2_Promise* msg) { + const grpc_channelz_v2_Promise_Loop* default_val = NULL; + const grpc_channelz_v2_Promise_Loop* ret; + const upb_MiniTableField field = {4, UPB_SIZE(12, 16), -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Loop_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_loop_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 16), -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_race_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(12, 16), -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_Race* grpc_channelz_v2_Promise_race_promise(const grpc_channelz_v2_Promise* msg) { + const grpc_channelz_v2_Promise_Race* default_val = NULL; + const grpc_channelz_v2_Promise_Race* ret; + const upb_MiniTableField field = {5, UPB_SIZE(12, 16), -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Race_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_race_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(12, 16), -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_seq_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(12, 16), -9, 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_Seq* grpc_channelz_v2_Promise_seq_promise(const grpc_channelz_v2_Promise* msg) { + const grpc_channelz_v2_Promise_Seq* default_val = NULL; + const grpc_channelz_v2_Promise_Seq* ret; + const upb_MiniTableField field = {6, UPB_SIZE(12, 16), -9, 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Seq_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_seq_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(12, 16), -9, 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_join_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), -9, 5, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_Join* grpc_channelz_v2_Promise_join_promise(const grpc_channelz_v2_Promise* msg) { + const grpc_channelz_v2_Promise_Join* default_val = NULL; + const grpc_channelz_v2_Promise_Join* ret; + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), -9, 5, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Join_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_join_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), -9, 5, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_clear_map_promise(grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(12, 16), -9, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_Map* grpc_channelz_v2_Promise_map_promise(const grpc_channelz_v2_Promise* msg) { + const grpc_channelz_v2_Promise_Map* default_val = NULL; + const grpc_channelz_v2_Promise_Map* ret; + const upb_MiniTableField field = {8, UPB_SIZE(12, 16), -9, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Map_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_has_map_promise(const grpc_channelz_v2_Promise* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(12, 16), -9, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void grpc_channelz_v2_Promise_set_custom_promise(grpc_channelz_v2_Promise *msg, grpc_channelz_v2_Promise_Custom* value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Custom_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise_Custom* grpc_channelz_v2_Promise_mutable_custom_promise(grpc_channelz_v2_Promise* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise_Custom* sub = (struct grpc_channelz_v2_Promise_Custom*)grpc_channelz_v2_Promise_custom_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise_Custom*)_upb_Message_New(&grpc__channelz__v2__Promise__Custom_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_set_custom_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_set_unknown_promise(grpc_channelz_v2_Promise *msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_set_if_promise(grpc_channelz_v2_Promise *msg, grpc_channelz_v2_Promise_If* value) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 16), -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__If_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise_If* grpc_channelz_v2_Promise_mutable_if_promise(grpc_channelz_v2_Promise* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise_If* sub = (struct grpc_channelz_v2_Promise_If*)grpc_channelz_v2_Promise_if_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise_If*)_upb_Message_New(&grpc__channelz__v2__Promise__If_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_set_if_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_set_loop_promise(grpc_channelz_v2_Promise *msg, grpc_channelz_v2_Promise_Loop* value) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 16), -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Loop_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise_Loop* grpc_channelz_v2_Promise_mutable_loop_promise(grpc_channelz_v2_Promise* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise_Loop* sub = (struct grpc_channelz_v2_Promise_Loop*)grpc_channelz_v2_Promise_loop_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise_Loop*)_upb_Message_New(&grpc__channelz__v2__Promise__Loop_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_set_loop_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_set_race_promise(grpc_channelz_v2_Promise *msg, grpc_channelz_v2_Promise_Race* value) { + const upb_MiniTableField field = {5, UPB_SIZE(12, 16), -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Race_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise_Race* grpc_channelz_v2_Promise_mutable_race_promise(grpc_channelz_v2_Promise* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise_Race* sub = (struct grpc_channelz_v2_Promise_Race*)grpc_channelz_v2_Promise_race_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise_Race*)_upb_Message_New(&grpc__channelz__v2__Promise__Race_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_set_race_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_set_seq_promise(grpc_channelz_v2_Promise *msg, grpc_channelz_v2_Promise_Seq* value) { + const upb_MiniTableField field = {6, UPB_SIZE(12, 16), -9, 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Seq_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise_Seq* grpc_channelz_v2_Promise_mutable_seq_promise(grpc_channelz_v2_Promise* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise_Seq* sub = (struct grpc_channelz_v2_Promise_Seq*)grpc_channelz_v2_Promise_seq_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise_Seq*)_upb_Message_New(&grpc__channelz__v2__Promise__Seq_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_set_seq_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_set_join_promise(grpc_channelz_v2_Promise *msg, grpc_channelz_v2_Promise_Join* value) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), -9, 5, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Join_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise_Join* grpc_channelz_v2_Promise_mutable_join_promise(grpc_channelz_v2_Promise* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise_Join* sub = (struct grpc_channelz_v2_Promise_Join*)grpc_channelz_v2_Promise_join_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise_Join*)_upb_Message_New(&grpc__channelz__v2__Promise__Join_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_set_join_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_set_map_promise(grpc_channelz_v2_Promise *msg, grpc_channelz_v2_Promise_Map* value) { + const upb_MiniTableField field = {8, UPB_SIZE(12, 16), -9, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__Map_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise_Map* grpc_channelz_v2_Promise_mutable_map_promise(grpc_channelz_v2_Promise* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise_Map* sub = (struct grpc_channelz_v2_Promise_Map*)grpc_channelz_v2_Promise_map_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise_Map*)_upb_Message_New(&grpc__channelz__v2__Promise__Map_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_set_map_promise(msg, sub); + } + return sub; +} + +/* grpc.channelz.v2.Promise.Custom */ + +UPB_INLINE grpc_channelz_v2_Promise_Custom* grpc_channelz_v2_Promise_Custom_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_Custom*)_upb_Message_New(&grpc__channelz__v2__Promise__Custom_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_Custom* grpc_channelz_v2_Promise_Custom_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_Custom* ret = grpc_channelz_v2_Promise_Custom_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Custom_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_Custom* grpc_channelz_v2_Promise_Custom_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_Custom* ret = grpc_channelz_v2_Promise_Custom_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Custom_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Custom_serialize(const grpc_channelz_v2_Promise_Custom* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Custom_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Custom_serialize_ex(const grpc_channelz_v2_Promise_Custom* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Custom_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_Custom_clear_type(grpc_channelz_v2_Promise_Custom* msg) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_Custom_type(const grpc_channelz_v2_Promise_Custom* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_Custom_clear_properties(grpc_channelz_v2_Promise_Custom* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const struct grpc_channelz_v2_PropertyList* grpc_channelz_v2_Promise_Custom_properties(const grpc_channelz_v2_Promise_Custom* msg) { + const struct grpc_channelz_v2_PropertyList* default_val = NULL; + const struct grpc_channelz_v2_PropertyList* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyList_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_Custom_has_properties(const grpc_channelz_v2_Promise_Custom* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void grpc_channelz_v2_Promise_Custom_set_type(grpc_channelz_v2_Promise_Custom *msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_Custom_set_properties(grpc_channelz_v2_Promise_Custom *msg, struct grpc_channelz_v2_PropertyList* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyList_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_PropertyList* grpc_channelz_v2_Promise_Custom_mutable_properties(grpc_channelz_v2_Promise_Custom* msg, upb_Arena* arena) { + struct grpc_channelz_v2_PropertyList* sub = (struct grpc_channelz_v2_PropertyList*)grpc_channelz_v2_Promise_Custom_properties(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_PropertyList*)_upb_Message_New(&grpc__channelz__v2__PropertyList_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_Custom_set_properties(msg, sub); + } + return sub; +} + +/* grpc.channelz.v2.Promise.If */ + +UPB_INLINE grpc_channelz_v2_Promise_If* grpc_channelz_v2_Promise_If_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_If*)_upb_Message_New(&grpc__channelz__v2__Promise__If_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_If* grpc_channelz_v2_Promise_If_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_If* ret = grpc_channelz_v2_Promise_If_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__If_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_If* grpc_channelz_v2_Promise_If_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_If* ret = grpc_channelz_v2_Promise_If_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__If_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_If_serialize(const grpc_channelz_v2_Promise_If* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__If_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_If_serialize_ex(const grpc_channelz_v2_Promise_If* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__If_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_If_clear_condition(grpc_channelz_v2_Promise_If* msg) { + const upb_MiniTableField field = {1, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool grpc_channelz_v2_Promise_If_condition(const grpc_channelz_v2_Promise_If* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {1, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_If_clear_true_factory(grpc_channelz_v2_Promise_If* msg) { + const upb_MiniTableField field = {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_If_true_factory(const grpc_channelz_v2_Promise_If* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_If_clear_false_factory(grpc_channelz_v2_Promise_If* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_If_false_factory(const grpc_channelz_v2_Promise_If* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_If_clear_promise(grpc_channelz_v2_Promise_If* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 48), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_If_promise(const grpc_channelz_v2_Promise_If* msg) { + const grpc_channelz_v2_Promise* default_val = NULL; + const grpc_channelz_v2_Promise* ret; + const upb_MiniTableField field = {4, UPB_SIZE(12, 48), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_If_has_promise(const grpc_channelz_v2_Promise_If* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 48), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void grpc_channelz_v2_Promise_If_set_condition(grpc_channelz_v2_Promise_If *msg, bool value) { + const upb_MiniTableField field = {1, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_If_set_true_factory(grpc_channelz_v2_Promise_If *msg, upb_StringView value) { + const upb_MiniTableField field = {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_If_set_false_factory(grpc_channelz_v2_Promise_If *msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_If_set_promise(grpc_channelz_v2_Promise_If *msg, grpc_channelz_v2_Promise* value) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 48), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_If_mutable_promise(grpc_channelz_v2_Promise_If* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise* sub = (struct grpc_channelz_v2_Promise*)grpc_channelz_v2_Promise_If_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise*)_upb_Message_New(&grpc__channelz__v2__Promise_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_If_set_promise(msg, sub); + } + return sub; +} + +/* grpc.channelz.v2.Promise.Loop */ + +UPB_INLINE grpc_channelz_v2_Promise_Loop* grpc_channelz_v2_Promise_Loop_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_Loop*)_upb_Message_New(&grpc__channelz__v2__Promise__Loop_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_Loop* grpc_channelz_v2_Promise_Loop_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_Loop* ret = grpc_channelz_v2_Promise_Loop_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Loop_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_Loop* grpc_channelz_v2_Promise_Loop_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_Loop* ret = grpc_channelz_v2_Promise_Loop_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Loop_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Loop_serialize(const grpc_channelz_v2_Promise_Loop* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Loop_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Loop_serialize_ex(const grpc_channelz_v2_Promise_Loop* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Loop_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_Loop_clear_loop_factory(grpc_channelz_v2_Promise_Loop* msg) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_Loop_loop_factory(const grpc_channelz_v2_Promise_Loop* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_Loop_clear_promise(grpc_channelz_v2_Promise_Loop* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_Loop_promise(const grpc_channelz_v2_Promise_Loop* msg) { + const grpc_channelz_v2_Promise* default_val = NULL; + const grpc_channelz_v2_Promise* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_Loop_has_promise(const grpc_channelz_v2_Promise_Loop* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_Loop_clear_yield(grpc_channelz_v2_Promise_Loop* msg) { + const upb_MiniTableField field = {3, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool grpc_channelz_v2_Promise_Loop_yield(const grpc_channelz_v2_Promise_Loop* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} + +UPB_INLINE void grpc_channelz_v2_Promise_Loop_set_loop_factory(grpc_channelz_v2_Promise_Loop *msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_Loop_set_promise(grpc_channelz_v2_Promise_Loop *msg, grpc_channelz_v2_Promise* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_Loop_mutable_promise(grpc_channelz_v2_Promise_Loop* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise* sub = (struct grpc_channelz_v2_Promise*)grpc_channelz_v2_Promise_Loop_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise*)_upb_Message_New(&grpc__channelz__v2__Promise_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_Loop_set_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_Loop_set_yield(grpc_channelz_v2_Promise_Loop *msg, bool value) { + const upb_MiniTableField field = {3, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} + +/* grpc.channelz.v2.Promise.Race */ + +UPB_INLINE grpc_channelz_v2_Promise_Race* grpc_channelz_v2_Promise_Race_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_Race*)_upb_Message_New(&grpc__channelz__v2__Promise__Race_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_Race* grpc_channelz_v2_Promise_Race_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_Race* ret = grpc_channelz_v2_Promise_Race_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Race_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_Race* grpc_channelz_v2_Promise_Race_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_Race* ret = grpc_channelz_v2_Promise_Race_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Race_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Race_serialize(const grpc_channelz_v2_Promise_Race* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Race_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Race_serialize_ex(const grpc_channelz_v2_Promise_Race* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Race_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_Race_clear_children(grpc_channelz_v2_Promise_Race* msg) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise* const* grpc_channelz_v2_Promise_Race_children(const grpc_channelz_v2_Promise_Race* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_Promise* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_Promise_Race_children_upb_array(const grpc_channelz_v2_Promise_Race* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_Promise_Race_children_mutable_upb_array(grpc_channelz_v2_Promise_Race* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE grpc_channelz_v2_Promise** grpc_channelz_v2_Promise_Race_mutable_children(grpc_channelz_v2_Promise_Race* msg, size_t* size) { + upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_Promise**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_Promise** grpc_channelz_v2_Promise_Race_resize_children(grpc_channelz_v2_Promise_Race* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_Promise**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_Race_add_children(grpc_channelz_v2_Promise_Race* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_Promise* sub = (struct grpc_channelz_v2_Promise*)_upb_Message_New(&grpc__channelz__v2__Promise_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.Promise.SeqStep */ + +UPB_INLINE grpc_channelz_v2_Promise_SeqStep* grpc_channelz_v2_Promise_SeqStep_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_SeqStep*)_upb_Message_New(&grpc__channelz__v2__Promise__SeqStep_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_SeqStep* grpc_channelz_v2_Promise_SeqStep_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_SeqStep* ret = grpc_channelz_v2_Promise_SeqStep_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__SeqStep_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_SeqStep* grpc_channelz_v2_Promise_SeqStep_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_SeqStep* ret = grpc_channelz_v2_Promise_SeqStep_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__SeqStep_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_SeqStep_serialize(const grpc_channelz_v2_Promise_SeqStep* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__SeqStep_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_SeqStep_serialize_ex(const grpc_channelz_v2_Promise_SeqStep* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__SeqStep_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_SeqStep_clear_factory(grpc_channelz_v2_Promise_SeqStep* msg) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_SeqStep_factory(const grpc_channelz_v2_Promise_SeqStep* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_SeqStep_clear_polling_promise(grpc_channelz_v2_Promise_SeqStep* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_SeqStep_polling_promise(const grpc_channelz_v2_Promise_SeqStep* msg) { + const grpc_channelz_v2_Promise* default_val = NULL; + const grpc_channelz_v2_Promise* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_SeqStep_has_polling_promise(const grpc_channelz_v2_Promise_SeqStep* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void grpc_channelz_v2_Promise_SeqStep_set_factory(grpc_channelz_v2_Promise_SeqStep *msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_SeqStep_set_polling_promise(grpc_channelz_v2_Promise_SeqStep *msg, grpc_channelz_v2_Promise* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_SeqStep_mutable_polling_promise(grpc_channelz_v2_Promise_SeqStep* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise* sub = (struct grpc_channelz_v2_Promise*)grpc_channelz_v2_Promise_SeqStep_polling_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise*)_upb_Message_New(&grpc__channelz__v2__Promise_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_SeqStep_set_polling_promise(msg, sub); + } + return sub; +} + +/* grpc.channelz.v2.Promise.Seq */ + +UPB_INLINE grpc_channelz_v2_Promise_Seq* grpc_channelz_v2_Promise_Seq_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_Seq*)_upb_Message_New(&grpc__channelz__v2__Promise__Seq_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_Seq* grpc_channelz_v2_Promise_Seq_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_Seq* ret = grpc_channelz_v2_Promise_Seq_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Seq_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_Seq* grpc_channelz_v2_Promise_Seq_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_Seq* ret = grpc_channelz_v2_Promise_Seq_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Seq_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Seq_serialize(const grpc_channelz_v2_Promise_Seq* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Seq_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Seq_serialize_ex(const grpc_channelz_v2_Promise_Seq* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Seq_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_Seq_clear_kind(grpc_channelz_v2_Promise_Seq* msg) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t grpc_channelz_v2_Promise_Seq_kind(const grpc_channelz_v2_Promise_Seq* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_Seq_clear_steps(grpc_channelz_v2_Promise_Seq* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_SeqStep* const* grpc_channelz_v2_Promise_Seq_steps(const grpc_channelz_v2_Promise_Seq* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__SeqStep_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_Promise_SeqStep* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_Promise_Seq_steps_upb_array(const grpc_channelz_v2_Promise_Seq* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__SeqStep_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_Promise_Seq_steps_mutable_upb_array(grpc_channelz_v2_Promise_Seq* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__SeqStep_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void grpc_channelz_v2_Promise_Seq_set_kind(grpc_channelz_v2_Promise_Seq *msg, int32_t value) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE grpc_channelz_v2_Promise_SeqStep** grpc_channelz_v2_Promise_Seq_mutable_steps(grpc_channelz_v2_Promise_Seq* msg, size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__SeqStep_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_Promise_SeqStep**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_Promise_SeqStep** grpc_channelz_v2_Promise_Seq_resize_steps(grpc_channelz_v2_Promise_Seq* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_Promise_SeqStep**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_Promise_SeqStep* grpc_channelz_v2_Promise_Seq_add_steps(grpc_channelz_v2_Promise_Seq* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__SeqStep_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_Promise_SeqStep* sub = (struct grpc_channelz_v2_Promise_SeqStep*)_upb_Message_New(&grpc__channelz__v2__Promise__SeqStep_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.Promise.JoinBranch */ + +UPB_INLINE grpc_channelz_v2_Promise_JoinBranch* grpc_channelz_v2_Promise_JoinBranch_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_JoinBranch*)_upb_Message_New(&grpc__channelz__v2__Promise__JoinBranch_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_JoinBranch* grpc_channelz_v2_Promise_JoinBranch_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_JoinBranch* ret = grpc_channelz_v2_Promise_JoinBranch_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__JoinBranch_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_JoinBranch* grpc_channelz_v2_Promise_JoinBranch_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_JoinBranch* ret = grpc_channelz_v2_Promise_JoinBranch_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__JoinBranch_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_JoinBranch_serialize(const grpc_channelz_v2_Promise_JoinBranch* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__JoinBranch_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_JoinBranch_serialize_ex(const grpc_channelz_v2_Promise_JoinBranch* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__JoinBranch_msg_init, options, arena, &ptr, len); + return ptr; +} +typedef enum { + grpc_channelz_v2_Promise_JoinBranch_state_polling_promise = 2, + grpc_channelz_v2_Promise_JoinBranch_state_result = 3, + grpc_channelz_v2_Promise_JoinBranch_state_NOT_SET = 0 +} grpc_channelz_v2_Promise_JoinBranch_state_oneofcases; +UPB_INLINE grpc_channelz_v2_Promise_JoinBranch_state_oneofcases grpc_channelz_v2_Promise_JoinBranch_state_case(const grpc_channelz_v2_Promise_JoinBranch* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(20, 32), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_Promise_JoinBranch_state_oneofcases)upb_Message_WhichOneofFieldNumber( + UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_JoinBranch_clear_state(grpc_channelz_v2_Promise_JoinBranch* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(20, 32), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearOneof(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__JoinBranch_msg_init, &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_JoinBranch_clear_factory(grpc_channelz_v2_Promise_JoinBranch* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_JoinBranch_factory(const grpc_channelz_v2_Promise_JoinBranch* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_JoinBranch_clear_polling_promise(grpc_channelz_v2_Promise_JoinBranch* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(20, 32), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_JoinBranch_polling_promise(const grpc_channelz_v2_Promise_JoinBranch* msg) { + const grpc_channelz_v2_Promise* default_val = NULL; + const grpc_channelz_v2_Promise* ret; + const upb_MiniTableField field = {2, UPB_SIZE(20, 32), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_JoinBranch_has_polling_promise(const grpc_channelz_v2_Promise_JoinBranch* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(20, 32), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_JoinBranch_clear_result(grpc_channelz_v2_Promise_JoinBranch* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 32), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_JoinBranch_result(const grpc_channelz_v2_Promise_JoinBranch* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(20, 32), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_JoinBranch_has_result(const grpc_channelz_v2_Promise_JoinBranch* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 32), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void grpc_channelz_v2_Promise_JoinBranch_set_factory(grpc_channelz_v2_Promise_JoinBranch *msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_Promise_JoinBranch_set_polling_promise(grpc_channelz_v2_Promise_JoinBranch *msg, grpc_channelz_v2_Promise* value) { + const upb_MiniTableField field = {2, UPB_SIZE(20, 32), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_JoinBranch_mutable_polling_promise(grpc_channelz_v2_Promise_JoinBranch* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise* sub = (struct grpc_channelz_v2_Promise*)grpc_channelz_v2_Promise_JoinBranch_polling_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise*)_upb_Message_New(&grpc__channelz__v2__Promise_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_JoinBranch_set_polling_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_JoinBranch_set_result(grpc_channelz_v2_Promise_JoinBranch *msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 32), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} + +/* grpc.channelz.v2.Promise.Join */ + +UPB_INLINE grpc_channelz_v2_Promise_Join* grpc_channelz_v2_Promise_Join_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_Join*)_upb_Message_New(&grpc__channelz__v2__Promise__Join_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_Join* grpc_channelz_v2_Promise_Join_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_Join* ret = grpc_channelz_v2_Promise_Join_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Join_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_Join* grpc_channelz_v2_Promise_Join_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_Join* ret = grpc_channelz_v2_Promise_Join_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Join_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Join_serialize(const grpc_channelz_v2_Promise_Join* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Join_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Join_serialize_ex(const grpc_channelz_v2_Promise_Join* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Join_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_Join_clear_kind(grpc_channelz_v2_Promise_Join* msg) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t grpc_channelz_v2_Promise_Join_kind(const grpc_channelz_v2_Promise_Join* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_Promise_Join_clear_branches(grpc_channelz_v2_Promise_Join* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise_JoinBranch* const* grpc_channelz_v2_Promise_Join_branches(const grpc_channelz_v2_Promise_Join* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__JoinBranch_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_Promise_JoinBranch* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_Promise_Join_branches_upb_array(const grpc_channelz_v2_Promise_Join* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__JoinBranch_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_Promise_Join_branches_mutable_upb_array(grpc_channelz_v2_Promise_Join* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__JoinBranch_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void grpc_channelz_v2_Promise_Join_set_kind(grpc_channelz_v2_Promise_Join *msg, int32_t value) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE grpc_channelz_v2_Promise_JoinBranch** grpc_channelz_v2_Promise_Join_mutable_branches(grpc_channelz_v2_Promise_Join* msg, size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__JoinBranch_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_Promise_JoinBranch**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_Promise_JoinBranch** grpc_channelz_v2_Promise_Join_resize_branches(grpc_channelz_v2_Promise_Join* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_Promise_JoinBranch**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_Promise_JoinBranch* grpc_channelz_v2_Promise_Join_add_branches(grpc_channelz_v2_Promise_Join* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise__JoinBranch_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_Promise_JoinBranch* sub = (struct grpc_channelz_v2_Promise_JoinBranch*)_upb_Message_New(&grpc__channelz__v2__Promise__JoinBranch_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.Promise.Map */ + +UPB_INLINE grpc_channelz_v2_Promise_Map* grpc_channelz_v2_Promise_Map_new(upb_Arena* arena) { + return (grpc_channelz_v2_Promise_Map*)_upb_Message_New(&grpc__channelz__v2__Promise__Map_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_Promise_Map* grpc_channelz_v2_Promise_Map_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_Promise_Map* ret = grpc_channelz_v2_Promise_Map_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Map_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_Promise_Map* grpc_channelz_v2_Promise_Map_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_Promise_Map* ret = grpc_channelz_v2_Promise_Map_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__Promise__Map_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Map_serialize(const grpc_channelz_v2_Promise_Map* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Map_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_Promise_Map_serialize_ex(const grpc_channelz_v2_Promise_Map* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__Promise__Map_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_Promise_Map_clear_promise(grpc_channelz_v2_Promise_Map* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_Map_promise(const grpc_channelz_v2_Promise_Map* msg) { + const grpc_channelz_v2_Promise* default_val = NULL; + const grpc_channelz_v2_Promise* ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_Promise_Map_has_promise(const grpc_channelz_v2_Promise_Map* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_Promise_Map_clear_map_fn(grpc_channelz_v2_Promise_Map* msg) { + const upb_MiniTableField field = {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_Promise_Map_map_fn(const grpc_channelz_v2_Promise_Map* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} + +UPB_INLINE void grpc_channelz_v2_Promise_Map_set_promise(grpc_channelz_v2_Promise_Map *msg, grpc_channelz_v2_Promise* value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__Promise_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct grpc_channelz_v2_Promise* grpc_channelz_v2_Promise_Map_mutable_promise(grpc_channelz_v2_Promise_Map* msg, upb_Arena* arena) { + struct grpc_channelz_v2_Promise* sub = (struct grpc_channelz_v2_Promise*)grpc_channelz_v2_Promise_Map_promise(msg); + if (sub == NULL) { + sub = (struct grpc_channelz_v2_Promise*)_upb_Message_New(&grpc__channelz__v2__Promise_msg_init, arena); + if (sub) grpc_channelz_v2_Promise_Map_set_promise(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_Promise_Map_set_map_fn(grpc_channelz_v2_Promise_Map *msg, upb_StringView value) { + const upb_MiniTableField field = {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPB_H_ */ diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c new file mode 100644 index 00000000000..b02885c7cb4 --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c @@ -0,0 +1,312 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/promise.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#include +#include "upb/generated_code_support.h" +#include "src/proto/grpc/channelz/v2/promise.upb_minitable.h" +#include "src/proto/grpc/channelz/v2/property_list.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_StaticallyTreeShaken); +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise__submsgs[7] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__Custom_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__If_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__Loop_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__Race_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__Seq_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__Join_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__Map_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise__fields[8] = { + {1, UPB_SIZE(12, 16), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 16), -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(12, 16), -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(12, 16), -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(12, 16), -9, 4, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(12, 16), -9, 5, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(12, 16), -9, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise_msg_init = { + &grpc_channelz_v2_Promise__submsgs[0], + &grpc_channelz_v2_Promise__fields[0], + UPB_SIZE(24, 32), 8, kUpb_ExtMode_NonExtendable, 8, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000080100000a, &upb_pom_1bt_max64b}, + {0x0010000802000012, &upb_pos_1bt}, + {0x001000080301001a, &upb_pom_1bt_max64b}, + {0x0010000804020022, &upb_pom_1bt_max64b}, + {0x001000080503002a, &upb_pom_1bt_max64b}, + {0x0010000806040032, &upb_pom_1bt_max64b}, + {0x001000080705003a, &upb_pom_1bt_max64b}, + {0x0010000808060042, &upb_pom_1bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise_msg_init_ptr = &grpc__channelz__v2__Promise_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_Custom__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__PropertyList_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_Custom__fields[2] = { + {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__Custom_msg_init = { + &grpc_channelz_v2_Promise_Custom__submsgs[0], + &grpc_channelz_v2_Promise_Custom__fields[0], + UPB_SIZE(24, 40), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.Custom", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f00000a, &upb_pss_1bt}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__Custom_msg_init_ptr = &grpc__channelz__v2__Promise__Custom_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_If__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_If__fields[4] = { + {1, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(24, 32), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(12, 48), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__If_msg_init = { + &grpc_channelz_v2_Promise_If__submsgs[0], + &grpc_channelz_v2_Promise_If__fields[0], + UPB_SIZE(32, 56), 4, kUpb_ExtMode_NonExtendable, 4, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.If", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000900003f000008, &upb_psb1_1bt}, + {0x001000003f000012, &upb_pss_1bt}, + {0x002000003f00001a, &upb_pss_1bt}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__If_msg_init_ptr = &grpc__channelz__v2__Promise__If_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_Loop__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_Loop__fields[3] = { + {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, 9, 0, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__Loop_msg_init = { + &grpc_channelz_v2_Promise_Loop__submsgs[0], + &grpc_channelz_v2_Promise_Loop__fields[0], + UPB_SIZE(24, 40), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.Loop", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f00000a, &upb_pss_1bt}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000900003f000018, &upb_psb1_1bt}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__Loop_msg_init_ptr = &grpc__channelz__v2__Promise__Loop_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_Race__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_Race__fields[1] = { + {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__Race_msg_init = { + &grpc_channelz_v2_Promise_Race__submsgs[0], + &grpc_channelz_v2_Promise_Race__fields[0], + 16, 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.Race", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800003f00000a, &upb_prm_1bt_max64b}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__Race_msg_init_ptr = &grpc__channelz__v2__Promise__Race_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_SeqStep__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_SeqStep__fields[2] = { + {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__SeqStep_msg_init = { + &grpc_channelz_v2_Promise_SeqStep__submsgs[0], + &grpc_channelz_v2_Promise_SeqStep__fields[0], + UPB_SIZE(24, 40), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.SeqStep", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f00000a, &upb_pss_1bt}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__SeqStep_msg_init_ptr = &grpc__channelz__v2__Promise__SeqStep_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_Seq__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__SeqStep_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_Seq__fields[2] = { + {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__Seq_msg_init = { + &grpc_channelz_v2_Promise_Seq__submsgs[0], + &grpc_channelz_v2_Promise_Seq__fields[0], + UPB_SIZE(16, 24), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.Seq", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800003f000008, &upb_psv4_1bt}, + {0x001000003f000012, &upb_prm_1bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__Seq_msg_init_ptr = &grpc__channelz__v2__Promise__Seq_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_JoinBranch__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_JoinBranch__fields[3] = { + {1, UPB_SIZE(12, 16), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(20, 32), -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(20, 32), -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__JoinBranch_msg_init = { + &grpc_channelz_v2_Promise_JoinBranch__submsgs[0], + &grpc_channelz_v2_Promise_JoinBranch__fields[0], + UPB_SIZE(32, 48), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.JoinBranch", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f00000a, &upb_pss_1bt}, + {0x0020000802000012, &upb_pom_1bt_max64b}, + {0x002000080300001a, &upb_pos_1bt}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__JoinBranch_msg_init_ptr = &grpc__channelz__v2__Promise__JoinBranch_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_Join__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise__JoinBranch_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_Join__fields[2] = { + {1, 8, 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__Join_msg_init = { + &grpc_channelz_v2_Promise_Join__submsgs[0], + &grpc_channelz_v2_Promise_Join__fields[0], + UPB_SIZE(16, 24), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.Join", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800003f000008, &upb_psv4_1bt}, + {0x001000003f000012, &upb_prm_1bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__Join_msg_init_ptr = &grpc__channelz__v2__Promise__Join_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_Promise_Map__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__Promise_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_Promise_Map__fields[2] = { + {1, UPB_SIZE(12, 32), 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__Promise__Map_msg_init = { + &grpc_channelz_v2_Promise_Map__submsgs[0], + &grpc_channelz_v2_Promise_Map__fields[0], + UPB_SIZE(24, 40), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.Promise.Map", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f000012, &upb_pss_1bt}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__Promise__Map_msg_init_ptr = &grpc__channelz__v2__Promise__Map_msg_init; +static const upb_MiniTable *messages_layout[10] = { + &grpc__channelz__v2__Promise_msg_init, + &grpc__channelz__v2__Promise__Custom_msg_init, + &grpc__channelz__v2__Promise__If_msg_init, + &grpc__channelz__v2__Promise__Loop_msg_init, + &grpc__channelz__v2__Promise__Race_msg_init, + &grpc__channelz__v2__Promise__SeqStep_msg_init, + &grpc__channelz__v2__Promise__Seq_msg_init, + &grpc__channelz__v2__Promise__JoinBranch_msg_init, + &grpc__channelz__v2__Promise__Join_msg_init, + &grpc__channelz__v2__Promise__Map_msg_init, +}; + +const upb_MiniTableFile src_proto_grpc_channelz_v2_promise_proto_upb_file_layout = { + messages_layout, + NULL, + NULL, + 10, + 0, + 0, +}; + +#include "upb/port/undef.inc" + diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h new file mode 100644 index 00000000000..1d09fd02d51 --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h @@ -0,0 +1,50 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/promise.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPB_MINITABLE_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPB_MINITABLE_H_ + +#include "upb/generated_code_support.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable grpc__channelz__v2__Promise_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__Custom_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__Custom_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__If_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__If_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__Loop_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__Loop_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__Race_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__Race_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__SeqStep_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__SeqStep_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__Seq_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__Seq_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__JoinBranch_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__JoinBranch_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__Join_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__Join_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__Promise__Map_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__Promise__Map_msg_init_ptr; + +extern const upb_MiniTableFile src_proto_grpc_channelz_v2_promise_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPB_MINITABLE_H_ */ diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h new file mode 100644 index 00000000000..b1702c7bc65 --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h @@ -0,0 +1,984 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/property_list.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPB_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPB_H_ + +#include "upb/generated_code_support.h" + +#include "src/proto/grpc/channelz/v2/property_list.upb_minitable.h" + +#include "google/protobuf/any.upb_minitable.h" +#include "google/protobuf/empty.upb_minitable.h" +#include "google/protobuf/timestamp.upb_minitable.h" +#include "google/protobuf/duration.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct grpc_channelz_v2_PropertyList { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_PropertyList; +typedef struct grpc_channelz_v2_PropertyGrid { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_PropertyGrid; +typedef struct grpc_channelz_v2_PropertyGrid_Row { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_PropertyGrid_Row; +typedef struct grpc_channelz_v2_PropertyTable { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_PropertyTable; +typedef struct grpc_channelz_v2_PropertyTable_Row { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_PropertyTable_Row; +typedef struct grpc_channelz_v2_PropertyValue { upb_Message UPB_PRIVATE(base); } grpc_channelz_v2_PropertyValue; +struct google_protobuf_Any; +struct google_protobuf_Duration; +struct google_protobuf_Empty; +struct google_protobuf_Timestamp; + + + +/* grpc.channelz.v2.PropertyList */ + +UPB_INLINE grpc_channelz_v2_PropertyList* grpc_channelz_v2_PropertyList_new(upb_Arena* arena) { + return (grpc_channelz_v2_PropertyList*)_upb_Message_New(&grpc__channelz__v2__PropertyList_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_PropertyList* grpc_channelz_v2_PropertyList_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_PropertyList* ret = grpc_channelz_v2_PropertyList_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyList_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_PropertyList* grpc_channelz_v2_PropertyList_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_PropertyList* ret = grpc_channelz_v2_PropertyList_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyList_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_PropertyList_serialize(const grpc_channelz_v2_PropertyList* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyList_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_PropertyList_serialize_ex(const grpc_channelz_v2_PropertyList* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyList_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_PropertyList_clear_properties(grpc_channelz_v2_PropertyList* msg) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE size_t grpc_channelz_v2_PropertyList_properties_size(const grpc_channelz_v2_PropertyList* msg) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Map* map = upb_Message_GetMap(UPB_UPCAST(msg), &field); + return map ? _upb_Map_Size(map) : 0; +} +UPB_INLINE bool grpc_channelz_v2_PropertyList_properties_get(const grpc_channelz_v2_PropertyList* msg, upb_StringView key, grpc_channelz_v2_PropertyValue** val) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init); + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + const upb_Map* map = upb_Message_GetMap(UPB_UPCAST(msg), &field); + if (!map) return false; + return _upb_Map_Get(map, &key, 0, val, sizeof(*val)); +} +UPB_INLINE bool grpc_channelz_v2_PropertyList_properties_next(const grpc_channelz_v2_PropertyList* msg, upb_StringView* key, const grpc_channelz_v2_PropertyValue** val, + size_t* iter) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init); + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + const upb_Map* map = upb_Message_GetMap(UPB_UPCAST(msg), &field); + if (!map) return false; + upb_MessageValue k; + upb_MessageValue v; + if (!upb_Map_Next(map, &k, &v, iter)) return false; + memcpy(key, &k, sizeof(*key)); + memcpy(val, &v, sizeof(*val)); + return true; +} +UPB_INLINE const upb_Map* _grpc_channelz_v2_PropertyList_properties_upb_map(grpc_channelz_v2_PropertyList* msg) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init); + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + return upb_Message_GetMap(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_Map* _grpc_channelz_v2_PropertyList_properties_mutable_upb_map(grpc_channelz_v2_PropertyList* msg, upb_Arena* a) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init); + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + return _upb_Message_GetOrCreateMutableMap(UPB_UPCAST(msg), &field, 0, sizeof(grpc_channelz_v2_PropertyValue*), a); +} + +UPB_INLINE void grpc_channelz_v2_PropertyList_properties_clear(grpc_channelz_v2_PropertyList* msg) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Map* map = (upb_Map*)upb_Message_GetMap(UPB_UPCAST(msg), &field); + if (!map) return; + _upb_Map_Clear(map); +} +UPB_INLINE bool grpc_channelz_v2_PropertyList_properties_set(grpc_channelz_v2_PropertyList* msg, upb_StringView key, grpc_channelz_v2_PropertyValue* val, upb_Arena* a) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init); + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + upb_Map* map = _upb_Message_GetOrCreateMutableMap(UPB_UPCAST(msg), + &field, 0, sizeof(val), a); + return _upb_Map_Insert(map, &key, 0, &val, sizeof(val), a) != + kUpb_MapInsertStatus_OutOfMemory; +} +UPB_INLINE bool grpc_channelz_v2_PropertyList_properties_delete(grpc_channelz_v2_PropertyList* msg, upb_StringView key) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Map* map = (upb_Map*)upb_Message_GetMap(UPB_UPCAST(msg), &field); + if (!map) return false; + return _upb_Map_Delete(map, &key, 0, NULL); +} + +/* grpc.channelz.v2.PropertyGrid */ + +UPB_INLINE grpc_channelz_v2_PropertyGrid* grpc_channelz_v2_PropertyGrid_new(upb_Arena* arena) { + return (grpc_channelz_v2_PropertyGrid*)_upb_Message_New(&grpc__channelz__v2__PropertyGrid_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_PropertyGrid* grpc_channelz_v2_PropertyGrid_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_PropertyGrid* ret = grpc_channelz_v2_PropertyGrid_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyGrid_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_PropertyGrid* grpc_channelz_v2_PropertyGrid_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_PropertyGrid* ret = grpc_channelz_v2_PropertyGrid_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyGrid_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_PropertyGrid_serialize(const grpc_channelz_v2_PropertyGrid* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyGrid_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_PropertyGrid_serialize_ex(const grpc_channelz_v2_PropertyGrid* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyGrid_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_PropertyGrid_clear_columns(grpc_channelz_v2_PropertyGrid* msg) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* grpc_channelz_v2_PropertyGrid_columns(const grpc_channelz_v2_PropertyGrid* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_PropertyGrid_columns_upb_array(const grpc_channelz_v2_PropertyGrid* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_PropertyGrid_columns_mutable_upb_array(grpc_channelz_v2_PropertyGrid* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void grpc_channelz_v2_PropertyGrid_clear_rows(grpc_channelz_v2_PropertyGrid* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_PropertyGrid_Row* const* grpc_channelz_v2_PropertyGrid_rows(const grpc_channelz_v2_PropertyGrid* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyGrid__Row_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_PropertyGrid_Row* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_PropertyGrid_rows_upb_array(const grpc_channelz_v2_PropertyGrid* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyGrid__Row_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_PropertyGrid_rows_mutable_upb_array(grpc_channelz_v2_PropertyGrid* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyGrid__Row_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_StringView* grpc_channelz_v2_PropertyGrid_mutable_columns(grpc_channelz_v2_PropertyGrid* msg, size_t* size) { + upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE upb_StringView* grpc_channelz_v2_PropertyGrid_resize_columns(grpc_channelz_v2_PropertyGrid* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE bool grpc_channelz_v2_PropertyGrid_add_columns(grpc_channelz_v2_PropertyGrid* msg, upb_StringView val, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE grpc_channelz_v2_PropertyGrid_Row** grpc_channelz_v2_PropertyGrid_mutable_rows(grpc_channelz_v2_PropertyGrid* msg, size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyGrid__Row_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_PropertyGrid_Row**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_PropertyGrid_Row** grpc_channelz_v2_PropertyGrid_resize_rows(grpc_channelz_v2_PropertyGrid* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_PropertyGrid_Row**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_PropertyGrid_Row* grpc_channelz_v2_PropertyGrid_add_rows(grpc_channelz_v2_PropertyGrid* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyGrid__Row_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_PropertyGrid_Row* sub = (struct grpc_channelz_v2_PropertyGrid_Row*)_upb_Message_New(&grpc__channelz__v2__PropertyGrid__Row_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.PropertyGrid.Row */ + +UPB_INLINE grpc_channelz_v2_PropertyGrid_Row* grpc_channelz_v2_PropertyGrid_Row_new(upb_Arena* arena) { + return (grpc_channelz_v2_PropertyGrid_Row*)_upb_Message_New(&grpc__channelz__v2__PropertyGrid__Row_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_PropertyGrid_Row* grpc_channelz_v2_PropertyGrid_Row_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_PropertyGrid_Row* ret = grpc_channelz_v2_PropertyGrid_Row_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyGrid__Row_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_PropertyGrid_Row* grpc_channelz_v2_PropertyGrid_Row_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_PropertyGrid_Row* ret = grpc_channelz_v2_PropertyGrid_Row_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyGrid__Row_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_PropertyGrid_Row_serialize(const grpc_channelz_v2_PropertyGrid_Row* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyGrid__Row_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_PropertyGrid_Row_serialize_ex(const grpc_channelz_v2_PropertyGrid_Row* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyGrid__Row_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_PropertyGrid_Row_clear_label(grpc_channelz_v2_PropertyGrid_Row* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 8), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_PropertyGrid_Row_label(const grpc_channelz_v2_PropertyGrid_Row* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 8), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE void grpc_channelz_v2_PropertyGrid_Row_clear_value(grpc_channelz_v2_PropertyGrid_Row* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_PropertyValue* const* grpc_channelz_v2_PropertyGrid_Row_value(const grpc_channelz_v2_PropertyGrid_Row* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_PropertyValue* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_PropertyGrid_Row_value_upb_array(const grpc_channelz_v2_PropertyGrid_Row* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_PropertyGrid_Row_value_mutable_upb_array(grpc_channelz_v2_PropertyGrid_Row* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void grpc_channelz_v2_PropertyGrid_Row_set_label(grpc_channelz_v2_PropertyGrid_Row *msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 8), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE grpc_channelz_v2_PropertyValue** grpc_channelz_v2_PropertyGrid_Row_mutable_value(grpc_channelz_v2_PropertyGrid_Row* msg, size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_PropertyValue**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_PropertyValue** grpc_channelz_v2_PropertyGrid_Row_resize_value(grpc_channelz_v2_PropertyGrid_Row* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_PropertyValue**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_PropertyValue* grpc_channelz_v2_PropertyGrid_Row_add_value(grpc_channelz_v2_PropertyGrid_Row* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_PropertyValue* sub = (struct grpc_channelz_v2_PropertyValue*)_upb_Message_New(&grpc__channelz__v2__PropertyValue_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.PropertyTable */ + +UPB_INLINE grpc_channelz_v2_PropertyTable* grpc_channelz_v2_PropertyTable_new(upb_Arena* arena) { + return (grpc_channelz_v2_PropertyTable*)_upb_Message_New(&grpc__channelz__v2__PropertyTable_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_PropertyTable* grpc_channelz_v2_PropertyTable_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_PropertyTable* ret = grpc_channelz_v2_PropertyTable_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyTable_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_PropertyTable* grpc_channelz_v2_PropertyTable_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_PropertyTable* ret = grpc_channelz_v2_PropertyTable_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyTable_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_PropertyTable_serialize(const grpc_channelz_v2_PropertyTable* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyTable_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_PropertyTable_serialize_ex(const grpc_channelz_v2_PropertyTable* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyTable_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_PropertyTable_clear_columns(grpc_channelz_v2_PropertyTable* msg) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* grpc_channelz_v2_PropertyTable_columns(const grpc_channelz_v2_PropertyTable* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_PropertyTable_columns_upb_array(const grpc_channelz_v2_PropertyTable* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_PropertyTable_columns_mutable_upb_array(grpc_channelz_v2_PropertyTable* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void grpc_channelz_v2_PropertyTable_clear_rows(grpc_channelz_v2_PropertyTable* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_PropertyTable_Row* const* grpc_channelz_v2_PropertyTable_rows(const grpc_channelz_v2_PropertyTable* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyTable__Row_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_PropertyTable_Row* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_PropertyTable_rows_upb_array(const grpc_channelz_v2_PropertyTable* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyTable__Row_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_PropertyTable_rows_mutable_upb_array(grpc_channelz_v2_PropertyTable* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyTable__Row_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_StringView* grpc_channelz_v2_PropertyTable_mutable_columns(grpc_channelz_v2_PropertyTable* msg, size_t* size) { + upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE upb_StringView* grpc_channelz_v2_PropertyTable_resize_columns(grpc_channelz_v2_PropertyTable* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE bool grpc_channelz_v2_PropertyTable_add_columns(grpc_channelz_v2_PropertyTable* msg, upb_StringView val, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE grpc_channelz_v2_PropertyTable_Row** grpc_channelz_v2_PropertyTable_mutable_rows(grpc_channelz_v2_PropertyTable* msg, size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyTable__Row_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_PropertyTable_Row**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_PropertyTable_Row** grpc_channelz_v2_PropertyTable_resize_rows(grpc_channelz_v2_PropertyTable* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_PropertyTable_Row**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_PropertyTable_Row* grpc_channelz_v2_PropertyTable_add_rows(grpc_channelz_v2_PropertyTable* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyTable__Row_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_PropertyTable_Row* sub = (struct grpc_channelz_v2_PropertyTable_Row*)_upb_Message_New(&grpc__channelz__v2__PropertyTable__Row_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.PropertyTable.Row */ + +UPB_INLINE grpc_channelz_v2_PropertyTable_Row* grpc_channelz_v2_PropertyTable_Row_new(upb_Arena* arena) { + return (grpc_channelz_v2_PropertyTable_Row*)_upb_Message_New(&grpc__channelz__v2__PropertyTable__Row_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_PropertyTable_Row* grpc_channelz_v2_PropertyTable_Row_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_PropertyTable_Row* ret = grpc_channelz_v2_PropertyTable_Row_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyTable__Row_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_PropertyTable_Row* grpc_channelz_v2_PropertyTable_Row_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_PropertyTable_Row* ret = grpc_channelz_v2_PropertyTable_Row_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyTable__Row_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_PropertyTable_Row_serialize(const grpc_channelz_v2_PropertyTable_Row* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyTable__Row_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_PropertyTable_Row_serialize_ex(const grpc_channelz_v2_PropertyTable_Row* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyTable__Row_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void grpc_channelz_v2_PropertyTable_Row_clear_value(grpc_channelz_v2_PropertyTable_Row* msg) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const grpc_channelz_v2_PropertyValue* const* grpc_channelz_v2_PropertyTable_Row_value(const grpc_channelz_v2_PropertyTable_Row* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const grpc_channelz_v2_PropertyValue* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE const upb_Array* _grpc_channelz_v2_PropertyTable_Row_value_upb_array(const grpc_channelz_v2_PropertyTable_Row* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE upb_Array* _grpc_channelz_v2_PropertyTable_Row_value_mutable_upb_array(grpc_channelz_v2_PropertyTable_Row* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE grpc_channelz_v2_PropertyValue** grpc_channelz_v2_PropertyTable_Row_mutable_value(grpc_channelz_v2_PropertyTable_Row* msg, size_t* size) { + upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (grpc_channelz_v2_PropertyValue**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} +UPB_INLINE grpc_channelz_v2_PropertyValue** grpc_channelz_v2_PropertyTable_Row_resize_value(grpc_channelz_v2_PropertyTable_Row* msg, size_t size, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_PropertyValue**)upb_Message_ResizeArrayUninitialized(UPB_UPCAST(msg), + &field, size, arena); +} +UPB_INLINE struct grpc_channelz_v2_PropertyValue* grpc_channelz_v2_PropertyTable_Row_add_value(grpc_channelz_v2_PropertyTable_Row* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&grpc__channelz__v2__PropertyValue_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct grpc_channelz_v2_PropertyValue* sub = (struct grpc_channelz_v2_PropertyValue*)_upb_Message_New(&grpc__channelz__v2__PropertyValue_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* grpc.channelz.v2.PropertyValue */ + +UPB_INLINE grpc_channelz_v2_PropertyValue* grpc_channelz_v2_PropertyValue_new(upb_Arena* arena) { + return (grpc_channelz_v2_PropertyValue*)_upb_Message_New(&grpc__channelz__v2__PropertyValue_msg_init, arena); +} +UPB_INLINE grpc_channelz_v2_PropertyValue* grpc_channelz_v2_PropertyValue_parse(const char* buf, size_t size, upb_Arena* arena) { + grpc_channelz_v2_PropertyValue* ret = grpc_channelz_v2_PropertyValue_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyValue_msg_init, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE grpc_channelz_v2_PropertyValue* grpc_channelz_v2_PropertyValue_parse_ex(const char* buf, size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + grpc_channelz_v2_PropertyValue* ret = grpc_channelz_v2_PropertyValue_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &grpc__channelz__v2__PropertyValue_msg_init, extreg, options, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* grpc_channelz_v2_PropertyValue_serialize(const grpc_channelz_v2_PropertyValue* msg, upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyValue_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* grpc_channelz_v2_PropertyValue_serialize_ex(const grpc_channelz_v2_PropertyValue* msg, int options, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyValue_msg_init, options, arena, &ptr, len); + return ptr; +} +typedef enum { + grpc_channelz_v2_PropertyValue_kind_empty_value = 1, + grpc_channelz_v2_PropertyValue_kind_any_value = 2, + grpc_channelz_v2_PropertyValue_kind_string_value = 3, + grpc_channelz_v2_PropertyValue_kind_int64_value = 4, + grpc_channelz_v2_PropertyValue_kind_uint64_value = 5, + grpc_channelz_v2_PropertyValue_kind_double_value = 6, + grpc_channelz_v2_PropertyValue_kind_bool_value = 7, + grpc_channelz_v2_PropertyValue_kind_timestamp_value = 8, + grpc_channelz_v2_PropertyValue_kind_duration_value = 9, + grpc_channelz_v2_PropertyValue_kind_NOT_SET = 0 +} grpc_channelz_v2_PropertyValue_kind_oneofcases; +UPB_INLINE grpc_channelz_v2_PropertyValue_kind_oneofcases grpc_channelz_v2_PropertyValue_kind_case(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {1, 16, -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (grpc_channelz_v2_PropertyValue_kind_oneofcases)upb_Message_WhichOneofFieldNumber( + UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_kind(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {1, 16, -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearOneof(UPB_UPCAST(msg), &grpc__channelz__v2__PropertyValue_msg_init, &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_empty_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {1, 16, -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const struct google_protobuf_Empty* grpc_channelz_v2_PropertyValue_empty_value(const grpc_channelz_v2_PropertyValue* msg) { + const struct google_protobuf_Empty* default_val = NULL; + const struct google_protobuf_Empty* ret; + const upb_MiniTableField field = {1, 16, -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Empty_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_empty_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {1, 16, -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_any_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {2, 16, -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const struct google_protobuf_Any* grpc_channelz_v2_PropertyValue_any_value(const grpc_channelz_v2_PropertyValue* msg) { + const struct google_protobuf_Any* default_val = NULL; + const struct google_protobuf_Any* ret; + const upb_MiniTableField field = {2, 16, -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Any_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_any_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {2, 16, -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_string_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {3, 16, -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView grpc_channelz_v2_PropertyValue_string_value(const grpc_channelz_v2_PropertyValue* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, 16, -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_string_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {3, 16, -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_int64_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {4, 16, -9, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int64_t grpc_channelz_v2_PropertyValue_int64_value(const grpc_channelz_v2_PropertyValue* msg) { + int64_t default_val = (int64_t)0ll; + int64_t ret; + const upb_MiniTableField field = {4, 16, -9, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_int64_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {4, 16, -9, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_uint64_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {5, 16, -9, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE uint64_t grpc_channelz_v2_PropertyValue_uint64_value(const grpc_channelz_v2_PropertyValue* msg) { + uint64_t default_val = (uint64_t)0ull; + uint64_t ret; + const upb_MiniTableField field = {5, 16, -9, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_uint64_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {5, 16, -9, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_double_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {6, 16, -9, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE double grpc_channelz_v2_PropertyValue_double_value(const grpc_channelz_v2_PropertyValue* msg) { + double default_val = 0; + double ret; + const upb_MiniTableField field = {6, 16, -9, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_double_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {6, 16, -9, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_bool_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {7, 16, -9, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_bool_value(const grpc_channelz_v2_PropertyValue* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {7, 16, -9, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_bool_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {7, 16, -9, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_timestamp_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {8, 16, -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const struct google_protobuf_Timestamp* grpc_channelz_v2_PropertyValue_timestamp_value(const grpc_channelz_v2_PropertyValue* msg) { + const struct google_protobuf_Timestamp* default_val = NULL; + const struct google_protobuf_Timestamp* ret; + const upb_MiniTableField field = {8, 16, -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Timestamp_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_timestamp_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {8, 16, -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_clear_duration_value(grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {9, 16, -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const struct google_protobuf_Duration* grpc_channelz_v2_PropertyValue_duration_value(const grpc_channelz_v2_PropertyValue* msg) { + const struct google_protobuf_Duration* default_val = NULL; + const struct google_protobuf_Duration* ret; + const upb_MiniTableField field = {9, 16, -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Duration_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool grpc_channelz_v2_PropertyValue_has_duration_value(const grpc_channelz_v2_PropertyValue* msg) { + const upb_MiniTableField field = {9, 16, -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_empty_value(grpc_channelz_v2_PropertyValue *msg, struct google_protobuf_Empty* value) { + const upb_MiniTableField field = {1, 16, -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Empty_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_Empty* grpc_channelz_v2_PropertyValue_mutable_empty_value(grpc_channelz_v2_PropertyValue* msg, upb_Arena* arena) { + struct google_protobuf_Empty* sub = (struct google_protobuf_Empty*)grpc_channelz_v2_PropertyValue_empty_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Empty*)_upb_Message_New(&google__protobuf__Empty_msg_init, arena); + if (sub) grpc_channelz_v2_PropertyValue_set_empty_value(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_any_value(grpc_channelz_v2_PropertyValue *msg, struct google_protobuf_Any* value) { + const upb_MiniTableField field = {2, 16, -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Any_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_Any* grpc_channelz_v2_PropertyValue_mutable_any_value(grpc_channelz_v2_PropertyValue* msg, upb_Arena* arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)grpc_channelz_v2_PropertyValue_any_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)_upb_Message_New(&google__protobuf__Any_msg_init, arena); + if (sub) grpc_channelz_v2_PropertyValue_set_any_value(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_string_value(grpc_channelz_v2_PropertyValue *msg, upb_StringView value) { + const upb_MiniTableField field = {3, 16, -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_int64_value(grpc_channelz_v2_PropertyValue *msg, int64_t value) { + const upb_MiniTableField field = {4, 16, -9, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_uint64_value(grpc_channelz_v2_PropertyValue *msg, uint64_t value) { + const upb_MiniTableField field = {5, 16, -9, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_double_value(grpc_channelz_v2_PropertyValue *msg, double value) { + const upb_MiniTableField field = {6, 16, -9, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_bool_value(grpc_channelz_v2_PropertyValue *msg, bool value) { + const upb_MiniTableField field = {7, 16, -9, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_timestamp_value(grpc_channelz_v2_PropertyValue *msg, struct google_protobuf_Timestamp* value) { + const upb_MiniTableField field = {8, 16, -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Timestamp_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_Timestamp* grpc_channelz_v2_PropertyValue_mutable_timestamp_value(grpc_channelz_v2_PropertyValue* msg, upb_Arena* arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)grpc_channelz_v2_PropertyValue_timestamp_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)_upb_Message_New(&google__protobuf__Timestamp_msg_init, arena); + if (sub) grpc_channelz_v2_PropertyValue_set_timestamp_value(msg, sub); + } + return sub; +} +UPB_INLINE void grpc_channelz_v2_PropertyValue_set_duration_value(grpc_channelz_v2_PropertyValue *msg, struct google_protobuf_Duration* value) { + const upb_MiniTableField field = {9, 16, -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__Duration_msg_init); + upb_Message_SetBaseField((upb_Message *)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_Duration* grpc_channelz_v2_PropertyValue_mutable_duration_value(grpc_channelz_v2_PropertyValue* msg, upb_Arena* arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)grpc_channelz_v2_PropertyValue_duration_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)_upb_Message_New(&google__protobuf__Duration_msg_init, arena); + if (sub) grpc_channelz_v2_PropertyValue_set_duration_value(msg, sub); + } + return sub; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPB_H_ */ diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c new file mode 100644 index 00000000000..89e18195755 --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c @@ -0,0 +1,226 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/property_list.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#include +#include "upb/generated_code_support.h" +#include "src/proto/grpc/channelz/v2/property_list.upb_minitable.h" +#include "google/protobuf/any.upb_minitable.h" +#include "google/protobuf/empty.upb_minitable.h" +#include "google/protobuf/timestamp.upb_minitable.h" +#include "google/protobuf/duration.upb_minitable.h" + +// Must be last. +#include "upb/port/def.inc" + +extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_StaticallyTreeShaken); +static const upb_MiniTableSubInternal grpc_channelz_v2_PropertyList__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_PropertyList__fields[1] = { + {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Map | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__PropertyList_msg_init = { + &grpc_channelz_v2_PropertyList__submsgs[0], + &grpc_channelz_v2_PropertyList__fields[0], + 16, 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.PropertyList", +#endif +}; + +const upb_MiniTable* grpc__channelz__v2__PropertyList_msg_init_ptr = &grpc__channelz__v2__PropertyList_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_PropertyList_PropertiesEntry__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__PropertyValue_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_PropertyList_PropertiesEntry__fields[2] = { + {1, 16, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, 32, 64, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init = { + &grpc_channelz_v2_PropertyList_PropertiesEntry__submsgs[0], + &grpc_channelz_v2_PropertyList_PropertiesEntry__fields[0], + 48, 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.PropertyList.PropertiesEntry", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000003f00000a, &upb_pss_1bt}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init_ptr = &grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_PropertyGrid__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__PropertyGrid__Row_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_PropertyGrid__fields[2] = { + {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__PropertyGrid_msg_init = { + &grpc_channelz_v2_PropertyGrid__submsgs[0], + &grpc_channelz_v2_PropertyGrid__fields[0], + UPB_SIZE(16, 24), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.PropertyGrid", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800003f00000a, &upb_prs_1bt}, + {0x001000003f000012, &upb_prm_1bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__PropertyGrid_msg_init_ptr = &grpc__channelz__v2__PropertyGrid_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_PropertyGrid_Row__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__PropertyValue_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_PropertyGrid_Row__fields[2] = { + {1, UPB_SIZE(12, 8), 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(8, 24), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__PropertyGrid__Row_msg_init = { + &grpc_channelz_v2_PropertyGrid_Row__submsgs[0], + &grpc_channelz_v2_PropertyGrid_Row__fields[0], + UPB_SIZE(24, 32), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.PropertyGrid.Row", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800003f00000a, &upb_pss_1bt}, + {0x001800003f000012, &upb_prm_1bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__PropertyGrid__Row_msg_init_ptr = &grpc__channelz__v2__PropertyGrid__Row_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_PropertyTable__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__PropertyTable__Row_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_PropertyTable__fields[2] = { + {1, 8, 0, kUpb_NoSub, 9, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__PropertyTable_msg_init = { + &grpc_channelz_v2_PropertyTable__submsgs[0], + &grpc_channelz_v2_PropertyTable__fields[0], + UPB_SIZE(16, 24), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.PropertyTable", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800003f00000a, &upb_prs_1bt}, + {0x001000003f000012, &upb_prm_1bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__PropertyTable_msg_init_ptr = &grpc__channelz__v2__PropertyTable_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_PropertyTable_Row__submsgs[1] = { + {.UPB_PRIVATE(submsg) = &grpc__channelz__v2__PropertyValue_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_PropertyTable_Row__fields[1] = { + {1, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__PropertyTable__Row_msg_init = { + &grpc_channelz_v2_PropertyTable_Row__submsgs[0], + &grpc_channelz_v2_PropertyTable_Row__fields[0], + 16, 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.PropertyTable.Row", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000800003f00000a, &upb_prm_1bt_max64b}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__PropertyTable__Row_msg_init_ptr = &grpc__channelz__v2__PropertyTable__Row_msg_init; +static const upb_MiniTableSubInternal grpc_channelz_v2_PropertyValue__submsgs[4] = { + {.UPB_PRIVATE(submsg) = &google__protobuf__Empty_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &google__protobuf__Any_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &google__protobuf__Timestamp_msg_init_ptr}, + {.UPB_PRIVATE(submsg) = &google__protobuf__Duration_msg_init_ptr}, +}; + +static const upb_MiniTableField grpc_channelz_v2_PropertyValue__fields[9] = { + {1, 16, -9, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, 16, -9, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, 16, -9, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, 16, -9, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {5, 16, -9, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {6, 16, -9, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {7, 16, -9, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {8, 16, -9, 2, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {9, 16, -9, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}; + +const upb_MiniTable grpc__channelz__v2__PropertyValue_msg_init = { + &grpc_channelz_v2_PropertyValue__submsgs[0], + &grpc_channelz_v2_PropertyValue__fields[0], + UPB_SIZE(24, 32), 9, kUpb_ExtMode_NonExtendable, 9, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "grpc.channelz.v2.PropertyValue", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000080100000a, &upb_pom_1bt_maxmaxb}, + {0x0010000802010012, &upb_pom_1bt_maxmaxb}, + {0x001000080300001a, &upb_pos_1bt}, + {0x0010000804000020, &upb_pov8_1bt}, + {0x0010000805000028, &upb_pov8_1bt}, + {0x0010000806000031, &upb_pof8_1bt}, + {0x0010000807000038, &upb_pob1_1bt}, + {0x0010000808020042, &upb_pom_1bt_maxmaxb}, + {0x001000080903004a, &upb_pom_1bt_maxmaxb}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTable* grpc__channelz__v2__PropertyValue_msg_init_ptr = &grpc__channelz__v2__PropertyValue_msg_init; +static const upb_MiniTable *messages_layout[7] = { + &grpc__channelz__v2__PropertyList_msg_init, + &grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init, + &grpc__channelz__v2__PropertyGrid_msg_init, + &grpc__channelz__v2__PropertyGrid__Row_msg_init, + &grpc__channelz__v2__PropertyTable_msg_init, + &grpc__channelz__v2__PropertyTable__Row_msg_init, + &grpc__channelz__v2__PropertyValue_msg_init, +}; + +const upb_MiniTableFile src_proto_grpc_channelz_v2_property_list_proto_upb_file_layout = { + messages_layout, + NULL, + NULL, + 7, + 0, + 0, +}; + +#include "upb/port/undef.inc" + diff --git a/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h new file mode 100644 index 00000000000..c580d6b0c14 --- /dev/null +++ b/deps/grpc/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h @@ -0,0 +1,44 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/property_list.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPB_MINITABLE_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPB_MINITABLE_H_ + +#include "upb/generated_code_support.h" + +// Must be last. +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable grpc__channelz__v2__PropertyList_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__PropertyList_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__PropertyList__PropertiesEntry_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__PropertyGrid_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__PropertyGrid_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__PropertyGrid__Row_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__PropertyGrid__Row_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__PropertyTable_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__PropertyTable_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__PropertyTable__Row_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__PropertyTable__Row_msg_init_ptr; +extern const upb_MiniTable grpc__channelz__v2__PropertyValue_msg_init; +extern const upb_MiniTable* grpc__channelz__v2__PropertyValue_msg_init_ptr; + +extern const upb_MiniTableFile src_proto_grpc_channelz_v2_property_list_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPB_MINITABLE_H_ */ diff --git a/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.c b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.c new file mode 100644 index 00000000000..47ffa6d16c8 --- /dev/null +++ b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.c @@ -0,0 +1,80 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/channelz.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + +#include "upb/reflection/def.h" +#include "src/proto/grpc/channelz/v2/channelz.upbdefs.h" +#include "src/proto/grpc/channelz/v2/channelz.upb_minitable.h" + +extern _upb_DefPool_Init google_protobuf_any_proto_upbdefinit; +extern _upb_DefPool_Init google_protobuf_timestamp_proto_upbdefinit; + +static const char descriptor[578] = { + '\n', ')', 's', 'r', 'c', '/', 'p', 'r', 'o', 't', 'o', '/', + 'g', 'r', 'p', 'c', '/', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '/', 'v', '2', '/', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '.', 'p', 'r', 'o', 't', 'o', '\022', '\020', 'g', 'r', 'p', + 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', + '2', '\032', '\031', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', + 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'n', 'y', '.', 'p', + 'r', 'o', 't', 'o', '\032', '\037', 'g', 'o', 'o', 'g', 'l', 'e', + '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'i', + 'm', 'e', 's', 't', 'a', 'm', 'p', '.', 'p', 'r', 'o', 't', + 'o', '\"', 'F', '\n', '\004', 'D', 'a', 't', 'a', '\022', '\022', '\n', + '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', + '\004', 'n', 'a', 'm', 'e', '\022', '*', '\n', '\005', 'v', 'a', 'l', + 'u', 'e', '\030', '\002', ' ', '\001', '(', '\013', '2', '\024', '.', 'g', + 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', + 'u', 'f', '.', 'A', 'n', 'y', 'R', '\005', 'v', 'a', 'l', 'u', + 'e', '\"', '\337', '\001', '\n', '\006', 'E', 'n', 't', 'i', 't', 'y', + '\022', '\016', '\n', '\002', 'i', 'd', '\030', '\001', ' ', '\001', '(', '\003', + 'R', '\002', 'i', 'd', '\022', '\022', '\n', '\004', 'k', 'i', 'n', 'd', + '\030', '\002', ' ', '\001', '(', '\t', 'R', '\004', 'k', 'i', 'n', 'd', + '\022', '\030', '\n', '\007', 'p', 'a', 'r', 'e', 'n', 't', 's', '\030', + '\003', ' ', '\003', '(', '\003', 'R', '\007', 'p', 'a', 'r', 'e', 'n', + 't', 's', '\022', '\032', '\n', '\010', 'o', 'r', 'p', 'h', 'a', 'n', + 'e', 'd', '\030', '\004', ' ', '\001', '(', '\010', 'R', '\010', 'o', 'r', + 'p', 'h', 'a', 'n', 'e', 'd', '\022', '\033', '\n', '\t', 't', 'i', + 'm', 'e', 'd', '_', 'o', 'u', 't', '\030', '\005', ' ', '\001', '(', + '\010', 'R', '\010', 't', 'i', 'm', 'e', 'd', 'O', 'u', 't', '\022', + '*', '\n', '\004', 'd', 'a', 't', 'a', '\030', '\006', ' ', '\003', '(', + '\013', '2', '\026', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', + 'n', 'n', 'e', 'l', 'z', '.', 'v', '2', '.', 'D', 'a', 't', + 'a', 'R', '\004', 'd', 'a', 't', 'a', '\022', '2', '\n', '\005', 't', + 'r', 'a', 'c', 'e', '\030', '\007', ' ', '\003', '(', '\013', '2', '\034', + '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', + 'l', 'z', '.', 'v', '2', '.', 'T', 'r', 'a', 'c', 'e', 'E', + 'v', 'e', 'n', 't', 'R', '\005', 't', 'r', 'a', 'c', 'e', '\"', + '\224', '\001', '\n', '\n', 'T', 'r', 'a', 'c', 'e', 'E', 'v', 'e', + 'n', 't', '\022', ' ', '\n', '\013', 'd', 'e', 's', 'c', 'r', 'i', + 'p', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\001', '(', '\t', 'R', + '\013', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', + '\022', '8', '\n', '\t', 't', 'i', 'm', 'e', 's', 't', 'a', 'm', + 'p', '\030', '\002', ' ', '\001', '(', '\013', '2', '\032', '.', 'g', 'o', + 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', + 'f', '.', 'T', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'R', + '\t', 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', '\022', '*', + '\n', '\004', 'd', 'a', 't', 'a', '\030', '\003', ' ', '\003', '(', '\013', + '2', '\026', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', + 'n', 'e', 'l', 'z', '.', 'v', '2', '.', 'D', 'a', 't', 'a', + 'R', '\004', 'd', 'a', 't', 'a', 'b', '\006', 'p', 'r', 'o', 't', + 'o', '3', +}; + +static _upb_DefPool_Init *deps[3] = { + &google_protobuf_any_proto_upbdefinit, + &google_protobuf_timestamp_proto_upbdefinit, + NULL, +}; + +_upb_DefPool_Init src_proto_grpc_channelz_v2_channelz_proto_upbdefinit = { + deps, + &src_proto_grpc_channelz_v2_channelz_proto_upb_file_layout, + "src/proto/grpc/channelz/v2/channelz.proto", + UPB_STRINGVIEW_INIT(descriptor, sizeof(descriptor)), +}; diff --git a/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.h b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.h new file mode 100644 index 00000000000..a77a10cac27 --- /dev/null +++ b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.h @@ -0,0 +1,47 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/channelz.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPBDEFS_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPBDEFS_H_ + +#include "upb/reflection/def.h" +#include "upb/reflection/internal/def_pool.h" + +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +extern _upb_DefPool_Init src_proto_grpc_channelz_v2_channelz_proto_upbdefinit; + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Data_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_channelz_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Data"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Entity_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_channelz_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Entity"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_TraceEvent_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_channelz_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.TraceEvent"); +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_CHANNELZ_PROTO_UPB_H__UPBDEFS_H_ */ diff --git a/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c new file mode 100644 index 00000000000..6d592db9fe4 --- /dev/null +++ b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c @@ -0,0 +1,175 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/promise.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + +#include "upb/reflection/def.h" +#include "src/proto/grpc/channelz/v2/promise.upbdefs.h" +#include "src/proto/grpc/channelz/v2/promise.upb_minitable.h" + +extern _upb_DefPool_Init src_proto_grpc_channelz_v2_property_list_proto_upbdefinit; + +static const char descriptor[1748] = { + '\n', '(', 's', 'r', 'c', '/', 'p', 'r', 'o', 't', 'o', '/', + 'g', 'r', 'p', 'c', '/', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '/', 'v', '2', '/', 'p', 'r', 'o', 'm', 'i', 's', 'e', + '.', 'p', 'r', 'o', 't', 'o', '\022', '\020', 'g', 'r', 'p', 'c', + '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', '2', + '\032', '.', 's', 'r', 'c', '/', 'p', 'r', 'o', 't', 'o', '/', + 'g', 'r', 'p', 'c', '/', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '/', 'v', '2', '/', 'p', 'r', 'o', 'p', 'e', 'r', 't', + 'y', '_', 'l', 'i', 's', 't', '.', 'p', 'r', 'o', 't', 'o', + '\"', '\335', '\014', '\n', '\007', 'P', 'r', 'o', 'm', 'i', 's', 'e', + '\022', 'I', '\n', '\016', 'c', 'u', 's', 't', 'o', 'm', '_', 'p', + 'r', 'o', 'm', 'i', 's', 'e', '\030', '\001', ' ', '\001', '(', '\013', + '2', ' ', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', + 'n', 'e', 'l', 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'm', + 'i', 's', 'e', '.', 'C', 'u', 's', 't', 'o', 'm', 'H', '\000', + 'R', '\r', 'c', 'u', 's', 't', 'o', 'm', 'P', 'r', 'o', 'm', + 'i', 's', 'e', '\022', ')', '\n', '\017', 'u', 'n', 'k', 'n', 'o', + 'w', 'n', '_', 'p', 'r', 'o', 'm', 'i', 's', 'e', '\030', '\002', + ' ', '\001', '(', '\t', 'H', '\000', 'R', '\016', 'u', 'n', 'k', 'n', + 'o', 'w', 'n', 'P', 'r', 'o', 'm', 'i', 's', 'e', '\022', '=', + '\n', '\n', 'i', 'f', '_', 'p', 'r', 'o', 'm', 'i', 's', 'e', + '\030', '\003', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'r', 'p', + 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', + '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', '.', 'I', 'f', + 'H', '\000', 'R', '\t', 'i', 'f', 'P', 'r', 'o', 'm', 'i', 's', + 'e', '\022', 'C', '\n', '\014', 'l', 'o', 'o', 'p', '_', 'p', 'r', + 'o', 'm', 'i', 's', 'e', '\030', '\004', ' ', '\001', '(', '\013', '2', + '\036', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', + 'e', 'l', 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', + 's', 'e', '.', 'L', 'o', 'o', 'p', 'H', '\000', 'R', '\013', 'l', + 'o', 'o', 'p', 'P', 'r', 'o', 'm', 'i', 's', 'e', '\022', 'C', + '\n', '\014', 'r', 'a', 'c', 'e', '_', 'p', 'r', 'o', 'm', 'i', + 's', 'e', '\030', '\005', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', + 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', + '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', '.', + 'R', 'a', 'c', 'e', 'H', '\000', 'R', '\013', 'r', 'a', 'c', 'e', + 'P', 'r', 'o', 'm', 'i', 's', 'e', '\022', '@', '\n', '\013', 's', + 'e', 'q', '_', 'p', 'r', 'o', 'm', 'i', 's', 'e', '\030', '\006', + ' ', '\001', '(', '\013', '2', '\035', '.', 'g', 'r', 'p', 'c', '.', + 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', '2', '.', + 'P', 'r', 'o', 'm', 'i', 's', 'e', '.', 'S', 'e', 'q', 'H', + '\000', 'R', '\n', 's', 'e', 'q', 'P', 'r', 'o', 'm', 'i', 's', + 'e', '\022', 'C', '\n', '\014', 'j', 'o', 'i', 'n', '_', 'p', 'r', + 'o', 'm', 'i', 's', 'e', '\030', '\007', ' ', '\001', '(', '\013', '2', + '\036', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', + 'e', 'l', 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', + 's', 'e', '.', 'J', 'o', 'i', 'n', 'H', '\000', 'R', '\013', 'j', + 'o', 'i', 'n', 'P', 'r', 'o', 'm', 'i', 's', 'e', '\022', '@', + '\n', '\013', 'm', 'a', 'p', '_', 'p', 'r', 'o', 'm', 'i', 's', + 'e', '\030', '\010', ' ', '\001', '(', '\013', '2', '\035', '.', 'g', 'r', + 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', + 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', '.', 'M', + 'a', 'p', 'H', '\000', 'R', '\n', 'm', 'a', 'p', 'P', 'r', 'o', + 'm', 'i', 's', 'e', '\032', '\\', '\n', '\006', 'C', 'u', 's', 't', + 'o', 'm', '\022', '\022', '\n', '\004', 't', 'y', 'p', 'e', '\030', '\001', + ' ', '\001', '(', '\t', 'R', '\004', 't', 'y', 'p', 'e', '\022', '>', + '\n', '\n', 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', + '\030', '\002', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'r', 'p', + 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', + '2', '.', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', 'L', 'i', + 's', 't', 'R', '\n', 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', + 'e', 's', '\032', '\237', '\001', '\n', '\002', 'I', 'f', '\022', '\034', '\n', + '\t', 'c', 'o', 'n', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\001', + ' ', '\001', '(', '\010', 'R', '\t', 'c', 'o', 'n', 'd', 'i', 't', + 'i', 'o', 'n', '\022', '!', '\n', '\014', 't', 'r', 'u', 'e', '_', + 'f', 'a', 'c', 't', 'o', 'r', 'y', '\030', '\002', ' ', '\001', '(', + '\t', 'R', '\013', 't', 'r', 'u', 'e', 'F', 'a', 'c', 't', 'o', + 'r', 'y', '\022', '#', '\n', '\r', 'f', 'a', 'l', 's', 'e', '_', + 'f', 'a', 'c', 't', 'o', 'r', 'y', '\030', '\003', ' ', '\001', '(', + '\t', 'R', '\014', 'f', 'a', 'l', 's', 'e', 'F', 'a', 'c', 't', + 'o', 'r', 'y', '\022', '3', '\n', '\007', 'p', 'r', 'o', 'm', 'i', + 's', 'e', '\030', '\004', ' ', '\001', '(', '\013', '2', '\031', '.', 'g', + 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', + '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', 'R', + '\007', 'p', 'r', 'o', 'm', 'i', 's', 'e', '\032', 't', '\n', '\004', + 'L', 'o', 'o', 'p', '\022', '!', '\n', '\014', 'l', 'o', 'o', 'p', + '_', 'f', 'a', 'c', 't', 'o', 'r', 'y', '\030', '\001', ' ', '\001', + '(', '\t', 'R', '\013', 'l', 'o', 'o', 'p', 'F', 'a', 'c', 't', + 'o', 'r', 'y', '\022', '3', '\n', '\007', 'p', 'r', 'o', 'm', 'i', + 's', 'e', '\030', '\002', ' ', '\001', '(', '\013', '2', '\031', '.', 'g', + 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', + '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', 'R', + '\007', 'p', 'r', 'o', 'm', 'i', 's', 'e', '\022', '\024', '\n', '\005', + 'y', 'i', 'e', 'l', 'd', '\030', '\003', ' ', '\001', '(', '\010', 'R', + '\005', 'y', 'i', 'e', 'l', 'd', '\032', '=', '\n', '\004', 'R', 'a', + 'c', 'e', '\022', '5', '\n', '\010', 'c', 'h', 'i', 'l', 'd', 'r', + 'e', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '\031', '.', 'g', + 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', + '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', 'R', + '\010', 'c', 'h', 'i', 'l', 'd', 'r', 'e', 'n', '\032', 'g', '\n', + '\007', 'S', 'e', 'q', 'S', 't', 'e', 'p', '\022', '\030', '\n', '\007', + 'f', 'a', 'c', 't', 'o', 'r', 'y', '\030', '\001', ' ', '\001', '(', + '\t', 'R', '\007', 'f', 'a', 'c', 't', 'o', 'r', 'y', '\022', 'B', + '\n', '\017', 'p', 'o', 'l', 'l', 'i', 'n', 'g', '_', 'p', 'r', + 'o', 'm', 'i', 's', 'e', '\030', '\002', ' ', '\001', '(', '\013', '2', + '\031', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', + 'e', 'l', 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', + 's', 'e', 'R', '\016', 'p', 'o', 'l', 'l', 'i', 'n', 'g', 'P', + 'r', 'o', 'm', 'i', 's', 'e', '\032', '}', '\n', '\003', 'S', 'e', + 'q', '\022', '=', '\n', '\004', 'k', 'i', 'n', 'd', '\030', '\001', ' ', + '\001', '(', '\016', '2', ')', '.', 'g', 'r', 'p', 'c', '.', 'c', + 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', '2', '.', 'P', + 'r', 'o', 'm', 'i', 's', 'e', '.', 'C', 'o', 'm', 'p', 'o', + 's', 'i', 't', 'i', 'o', 'n', 'K', 'i', 'n', 'd', 'R', '\004', + 'k', 'i', 'n', 'd', '\022', '7', '\n', '\005', 's', 't', 'e', 'p', + 's', '\030', '\002', ' ', '\003', '(', '\013', '2', '!', '.', 'g', 'r', + 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', + 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', '.', 'S', + 'e', 'q', 'S', 't', 'e', 'p', 'R', '\005', 's', 't', 'e', 'p', + 's', '\032', '\217', '\001', '\n', '\n', 'J', 'o', 'i', 'n', 'B', 'r', + 'a', 'n', 'c', 'h', '\022', '\030', '\n', '\007', 'f', 'a', 'c', 't', + 'o', 'r', 'y', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\007', 'f', + 'a', 'c', 't', 'o', 'r', 'y', '\022', 'D', '\n', '\017', 'p', 'o', + 'l', 'l', 'i', 'n', 'g', '_', 'p', 'r', 'o', 'm', 'i', 's', + 'e', '\030', '\002', ' ', '\001', '(', '\013', '2', '\031', '.', 'g', 'r', + 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', + 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', 'H', '\000', + 'R', '\016', 'p', 'o', 'l', 'l', 'i', 'n', 'g', 'P', 'r', 'o', + 'm', 'i', 's', 'e', '\022', '\030', '\n', '\006', 'r', 'e', 's', 'u', + 'l', 't', '\030', '\003', ' ', '\001', '(', '\t', 'H', '\000', 'R', '\006', + 'r', 'e', 's', 'u', 'l', 't', 'B', '\007', '\n', '\005', 's', 't', + 'a', 't', 'e', '\032', '\207', '\001', '\n', '\004', 'J', 'o', 'i', 'n', + '\022', '=', '\n', '\004', 'k', 'i', 'n', 'd', '\030', '\001', ' ', '\001', + '(', '\016', '2', ')', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', + 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', '2', '.', 'P', 'r', + 'o', 'm', 'i', 's', 'e', '.', 'C', 'o', 'm', 'p', 'o', 's', + 'i', 't', 'i', 'o', 'n', 'K', 'i', 'n', 'd', 'R', '\004', 'k', + 'i', 'n', 'd', '\022', '@', '\n', '\010', 'b', 'r', 'a', 'n', 'c', + 'h', 'e', 's', '\030', '\002', ' ', '\003', '(', '\013', '2', '$', '.', + 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', + '.', 'J', 'o', 'i', 'n', 'B', 'r', 'a', 'n', 'c', 'h', 'R', + '\010', 'b', 'r', 'a', 'n', 'c', 'h', 'e', 's', '\032', 'Q', '\n', + '\003', 'M', 'a', 'p', '\022', '3', '\n', '\007', 'p', 'r', 'o', 'm', + 'i', 's', 'e', '\030', '\001', ' ', '\001', '(', '\013', '2', '\031', '.', + 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'm', 'i', 's', 'e', + 'R', '\007', 'p', 'r', 'o', 'm', 'i', 's', 'e', '\022', '\025', '\n', + '\006', 'm', 'a', 'p', '_', 'f', 'n', '\030', '\002', ' ', '\001', '(', + '\t', 'R', '\005', 'm', 'a', 'p', 'F', 'n', '\"', '3', '\n', '\017', + 'C', 'o', 'm', 'p', 'o', 's', 'i', 't', 'i', 'o', 'n', 'K', + 'i', 'n', 'd', '\022', '\013', '\n', '\007', 'U', 'N', 'K', 'N', 'O', + 'W', 'N', '\020', '\000', '\022', '\n', '\n', '\006', 'N', 'O', 'R', 'M', + 'A', 'L', '\020', '\001', '\022', '\007', '\n', '\003', 'T', 'R', 'Y', '\020', + '\002', 'B', '\t', '\n', '\007', 'p', 'r', 'o', 'm', 'i', 's', 'e', + 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static _upb_DefPool_Init *deps[2] = { + &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit, + NULL, +}; + +_upb_DefPool_Init src_proto_grpc_channelz_v2_promise_proto_upbdefinit = { + deps, + &src_proto_grpc_channelz_v2_promise_proto_upb_file_layout, + "src/proto/grpc/channelz/v2/promise.proto", + UPB_STRINGVIEW_INIT(descriptor, sizeof(descriptor)), +}; diff --git a/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h new file mode 100644 index 00000000000..637a3783dd8 --- /dev/null +++ b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h @@ -0,0 +1,82 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/promise.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPBDEFS_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPBDEFS_H_ + +#include "upb/reflection/def.h" +#include "upb/reflection/internal/def_pool.h" + +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +extern _upb_DefPool_Init src_proto_grpc_channelz_v2_promise_proto_upbdefinit; + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_Custom_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.Custom"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_If_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.If"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_Loop_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.Loop"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_Race_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.Race"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_SeqStep_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.SeqStep"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_Seq_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.Seq"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_JoinBranch_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.JoinBranch"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_Join_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.Join"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_Promise_Map_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_promise_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.Promise.Map"); +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_PROMISE_PROTO_UPB_H__UPBDEFS_H_ */ diff --git a/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c new file mode 100644 index 00000000000..92163fb2d70 --- /dev/null +++ b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c @@ -0,0 +1,135 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/property_list.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + +#include "upb/reflection/def.h" +#include "src/proto/grpc/channelz/v2/property_list.upbdefs.h" +#include "src/proto/grpc/channelz/v2/property_list.upb_minitable.h" + +extern _upb_DefPool_Init google_protobuf_any_proto_upbdefinit; +extern _upb_DefPool_Init google_protobuf_empty_proto_upbdefinit; +extern _upb_DefPool_Init google_protobuf_timestamp_proto_upbdefinit; +extern _upb_DefPool_Init google_protobuf_duration_proto_upbdefinit; + +static const char descriptor[1190] = { + '\n', '.', 's', 'r', 'c', '/', 'p', 'r', 'o', 't', 'o', '/', + 'g', 'r', 'p', 'c', '/', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '/', 'v', '2', '/', 'p', 'r', 'o', 'p', 'e', 'r', 't', + 'y', '_', 'l', 'i', 's', 't', '.', 'p', 'r', 'o', 't', 'o', + '\022', '\020', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', + 'e', 'l', 'z', '.', 'v', '2', '\032', '\031', 'g', 'o', 'o', 'g', + 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', + 'a', 'n', 'y', '.', 'p', 'r', 'o', 't', 'o', '\032', '\033', 'g', + 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', + 'u', 'f', '/', 'e', 'm', 'p', 't', 'y', '.', 'p', 'r', 'o', + 't', 'o', '\032', '\037', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', + 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'i', 'm', 'e', + 's', 't', 'a', 'm', 'p', '.', 'p', 'r', 'o', 't', 'o', '\032', + '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', + 'o', 'b', 'u', 'f', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', + 'n', '.', 'p', 'r', 'o', 't', 'o', '\"', '\276', '\001', '\n', '\014', + 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', 'L', 'i', 's', 't', + '\022', 'N', '\n', '\n', 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', + 'e', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', '.', '.', 'g', + 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', + '.', 'v', '2', '.', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', + 'L', 'i', 's', 't', '.', 'P', 'r', 'o', 'p', 'e', 'r', 't', + 'i', 'e', 's', 'E', 'n', 't', 'r', 'y', 'R', '\n', 'p', 'r', + 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', '\032', '^', '\n', '\017', + 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', 'E', 'n', + 't', 'r', 'y', '\022', '\020', '\n', '\003', 'k', 'e', 'y', '\030', '\001', + ' ', '\001', '(', '\t', 'R', '\003', 'k', 'e', 'y', '\022', '5', '\n', + '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\013', + '2', '\037', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', + 'n', 'e', 'l', 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'p', + 'e', 'r', 't', 'y', 'V', 'a', 'l', 'u', 'e', 'R', '\005', 'v', + 'a', 'l', 'u', 'e', ':', '\002', '8', '\001', '\"', '\264', '\001', '\n', + '\014', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', 'G', 'r', 'i', + 'd', '\022', '\030', '\n', '\007', 'c', 'o', 'l', 'u', 'm', 'n', 's', + '\030', '\001', ' ', '\003', '(', '\t', 'R', '\007', 'c', 'o', 'l', 'u', + 'm', 'n', 's', '\022', '6', '\n', '\004', 'r', 'o', 'w', 's', '\030', + '\002', ' ', '\003', '(', '\013', '2', '\"', '.', 'g', 'r', 'p', 'c', + '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', '2', + '.', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', 'G', 'r', 'i', + 'd', '.', 'R', 'o', 'w', 'R', '\004', 'r', 'o', 'w', 's', '\032', + 'R', '\n', '\003', 'R', 'o', 'w', '\022', '\024', '\n', '\005', 'l', 'a', + 'b', 'e', 'l', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\005', 'l', + 'a', 'b', 'e', 'l', '\022', '5', '\n', '\005', 'v', 'a', 'l', 'u', + 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '\037', '.', 'g', 'r', + 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', 'z', '.', + 'v', '2', '.', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', 'V', + 'a', 'l', 'u', 'e', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\"', + '\240', '\001', '\n', '\r', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', + 'T', 'a', 'b', 'l', 'e', '\022', '\030', '\n', '\007', 'c', 'o', 'l', + 'u', 'm', 'n', 's', '\030', '\001', ' ', '\003', '(', '\t', 'R', '\007', + 'c', 'o', 'l', 'u', 'm', 'n', 's', '\022', '7', '\n', '\004', 'r', + 'o', 'w', 's', '\030', '\002', ' ', '\003', '(', '\013', '2', '#', '.', + 'g', 'r', 'p', 'c', '.', 'c', 'h', 'a', 'n', 'n', 'e', 'l', + 'z', '.', 'v', '2', '.', 'P', 'r', 'o', 'p', 'e', 'r', 't', + 'y', 'T', 'a', 'b', 'l', 'e', '.', 'R', 'o', 'w', 'R', '\004', + 'r', 'o', 'w', 's', '\032', '<', '\n', '\003', 'R', 'o', 'w', '\022', + '5', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\003', + '(', '\013', '2', '\037', '.', 'g', 'r', 'p', 'c', '.', 'c', 'h', + 'a', 'n', 'n', 'e', 'l', 'z', '.', 'v', '2', '.', 'P', 'r', + 'o', 'p', 'e', 'r', 't', 'y', 'V', 'a', 'l', 'u', 'e', 'R', + '\005', 'v', 'a', 'l', 'u', 'e', '\"', '\305', '\003', '\n', '\r', 'P', + 'r', 'o', 'p', 'e', 'r', 't', 'y', 'V', 'a', 'l', 'u', 'e', + '\022', '9', '\n', '\013', 'e', 'm', 'p', 't', 'y', '_', 'v', 'a', + 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\013', '2', '\026', '.', + 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', + 'b', 'u', 'f', '.', 'E', 'm', 'p', 't', 'y', 'H', '\000', 'R', + '\n', 'e', 'm', 'p', 't', 'y', 'V', 'a', 'l', 'u', 'e', '\022', + '3', '\n', '\t', 'a', 'n', 'y', '_', 'v', 'a', 'l', 'u', 'e', + '\030', '\002', ' ', '\001', '(', '\013', '2', '\024', '.', 'g', 'o', 'o', + 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', + '.', 'A', 'n', 'y', 'H', '\000', 'R', '\010', 'a', 'n', 'y', 'V', + 'a', 'l', 'u', 'e', '\022', '#', '\n', '\014', 's', 't', 'r', 'i', + 'n', 'g', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', + '(', '\t', 'H', '\000', 'R', '\013', 's', 't', 'r', 'i', 'n', 'g', + 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\013', 'i', 'n', 't', + '6', '4', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ', '\001', + '(', '\003', 'H', '\000', 'R', '\n', 'i', 'n', 't', '6', '4', 'V', + 'a', 'l', 'u', 'e', '\022', '#', '\n', '\014', 'u', 'i', 'n', 't', + '6', '4', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\005', ' ', '\001', + '(', '\004', 'H', '\000', 'R', '\013', 'u', 'i', 'n', 't', '6', '4', + 'V', 'a', 'l', 'u', 'e', '\022', '#', '\n', '\014', 'd', 'o', 'u', + 'b', 'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', + '\001', '(', '\001', 'H', '\000', 'R', '\013', 'd', 'o', 'u', 'b', 'l', + 'e', 'V', 'a', 'l', 'u', 'e', '\022', '\037', '\n', '\n', 'b', 'o', + 'o', 'l', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', ' ', '\001', + '(', '\010', 'H', '\000', 'R', '\t', 'b', 'o', 'o', 'l', 'V', 'a', + 'l', 'u', 'e', '\022', 'E', '\n', '\017', 't', 'i', 'm', 'e', 's', + 't', 'a', 'm', 'p', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', + ' ', '\001', '(', '\013', '2', '\032', '.', 'g', 'o', 'o', 'g', 'l', + 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'T', + 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'H', '\000', 'R', '\016', + 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'V', 'a', 'l', + 'u', 'e', '\022', 'B', '\n', '\016', 'd', 'u', 'r', 'a', 't', 'i', + 'o', 'n', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\t', ' ', '\001', + '(', '\013', '2', '\031', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', + 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'u', 'r', + 'a', 't', 'i', 'o', 'n', 'H', '\000', 'R', '\r', 'd', 'u', 'r', + 'a', 't', 'i', 'o', 'n', 'V', 'a', 'l', 'u', 'e', 'B', '\006', + '\n', '\004', 'k', 'i', 'n', 'd', 'b', '\006', 'p', 'r', 'o', 't', + 'o', '3', +}; + +static _upb_DefPool_Init *deps[5] = { + &google_protobuf_any_proto_upbdefinit, + &google_protobuf_empty_proto_upbdefinit, + &google_protobuf_timestamp_proto_upbdefinit, + &google_protobuf_duration_proto_upbdefinit, + NULL, +}; + +_upb_DefPool_Init src_proto_grpc_channelz_v2_property_list_proto_upbdefinit = { + deps, + &src_proto_grpc_channelz_v2_property_list_proto_upb_file_layout, + "src/proto/grpc/channelz/v2/property_list.proto", + UPB_STRINGVIEW_INIT(descriptor, sizeof(descriptor)), +}; diff --git a/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h new file mode 100644 index 00000000000..c92206cafef --- /dev/null +++ b/deps/grpc/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h @@ -0,0 +1,67 @@ +/* This file was generated by upb_generator from the input file: + * + * src/proto/grpc/channelz/v2/property_list.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + + +#ifndef SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPBDEFS_H_ +#define SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPBDEFS_H_ + +#include "upb/reflection/def.h" +#include "upb/reflection/internal/def_pool.h" + +#include "upb/port/def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +extern _upb_DefPool_Init src_proto_grpc_channelz_v2_property_list_proto_upbdefinit; + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_PropertyList_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.PropertyList"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_PropertyList_PropertiesEntry_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.PropertyList.PropertiesEntry"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_PropertyGrid_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.PropertyGrid"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_PropertyGrid_Row_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.PropertyGrid.Row"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_PropertyTable_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.PropertyTable"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_PropertyTable_Row_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.PropertyTable.Row"); +} + +UPB_INLINE const upb_MessageDef *grpc_channelz_v2_PropertyValue_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &src_proto_grpc_channelz_v2_property_list_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "grpc.channelz.v2.PropertyValue"); +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* SRC_PROTO_GRPC_CHANNELZ_V2_PROPERTY_LIST_PROTO_UPB_H__UPBDEFS_H_ */ diff --git a/deps/grpc/src/core/filter/auth/auth_filters.h b/deps/grpc/src/core/filter/auth/auth_filters.h index 0d46c23d029..ef089b53de2 100644 --- a/deps/grpc/src/core/filter/auth/auth_filters.h +++ b/deps/grpc/src/core/filter/auth/auth_filters.h @@ -127,31 +127,6 @@ class ClientAuthFilter final : public ImplementChannelFilter { grpc_call_credentials::GetRequestMetadataArgs args_; }; -class LegacyClientAuthFilter final : public ChannelFilter { - public: - static const grpc_channel_filter kFilter; - - static absl::string_view TypeName() { return "client-auth-filter"; } - - LegacyClientAuthFilter( - RefCountedPtr security_connector, - RefCountedPtr auth_context); - - static absl::StatusOr> Create( - const ChannelArgs& args, ChannelFilter::Args); - - // Construct a promise for one call. - ArenaPromise MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) override; - - private: - ArenaPromise> GetCallCredsMetadata( - CallArgs call_args); - - // Contains refs to security connector and auth context. - grpc_call_credentials::GetRequestMetadataArgs args_; -}; - class ServerAuthFilter final : public ImplementChannelFilter { private: class RunApplicationCode { diff --git a/deps/grpc/src/core/filter/auth/client_auth_filter.cc b/deps/grpc/src/core/filter/auth/client_auth_filter.cc index c43881b1941..516a58e614b 100644 --- a/deps/grpc/src/core/filter/auth/client_auth_filter.cc +++ b/deps/grpc/src/core/filter/auth/client_auth_filter.cc @@ -189,122 +189,4 @@ absl::StatusOr> ClientAuthFilter::Create( const grpc_channel_filter ClientAuthFilter::kFilter = MakePromiseBasedFilter(); -// LegacyClientAuthFilter - -LegacyClientAuthFilter::LegacyClientAuthFilter( - RefCountedPtr security_connector, - RefCountedPtr auth_context) - : args_{std::move(security_connector), std::move(auth_context)} {} - -ArenaPromise> -LegacyClientAuthFilter::GetCallCredsMetadata(CallArgs call_args) { - auto* ctx = GetContext(); - grpc_call_credentials* channel_call_creds = - args_.security_connector->mutable_request_metadata_creds(); - const bool call_creds_has_md = (ctx != nullptr) && (ctx->creds != nullptr); - - if (channel_call_creds == nullptr && !call_creds_has_md) { - // Skip sending metadata altogether. - return Immediate(absl::StatusOr(std::move(call_args))); - } - - RefCountedPtr creds; - if (channel_call_creds != nullptr && call_creds_has_md) { - creds = RefCountedPtr( - grpc_composite_call_credentials_create(channel_call_creds, - ctx->creds.get(), nullptr)); - if (creds == nullptr) { - return Immediate(absl::UnauthenticatedError( - "Incompatible credentials set on channel and call.")); - } - } else if (call_creds_has_md) { - creds = ctx->creds->Ref(); - } else { - creds = channel_call_creds->Ref(); - } - - // Check security level of call credential and channel, and do not send - // metadata if the check fails. - grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( - args_.auth_context.get(), GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME); - const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it); - if (prop == nullptr) { - return Immediate( - absl::UnauthenticatedError("Established channel does not have an auth " - "property representing a security level.")); - } - const grpc_security_level call_cred_security_level = - creds->min_security_level(); - const bool is_security_level_ok = grpc_check_security_level( - convert_security_level_string_to_enum(prop->value), - call_cred_security_level); - if (!is_security_level_ok) { - return Immediate(absl::UnauthenticatedError( - "Established channel does not have a sufficient security level to " - "transfer call credential.")); - } - - auto client_initial_metadata = std::move(call_args.client_initial_metadata); - return TrySeq( - Seq(creds->GetRequestMetadata(std::move(client_initial_metadata), &args_), - [](absl::StatusOr new_metadata) mutable { - if (!new_metadata.ok()) { - return absl::StatusOr( - MaybeRewriteIllegalStatusCode(new_metadata.status(), - "call credentials")); - } - return new_metadata; - }), - [call_args = - std::move(call_args)](ClientMetadataHandle new_metadata) mutable { - call_args.client_initial_metadata = std::move(new_metadata); - return Immediate>( - absl::StatusOr(std::move(call_args))); - }); -} - -ArenaPromise LegacyClientAuthFilter::MakeCallPromise( - CallArgs call_args, NextPromiseFactory next_promise_factory) { - auto* sec_ctx = MaybeGetContext(); - if (sec_ctx == nullptr) { - sec_ctx = grpc_client_security_context_create(GetContext(), - /*creds=*/nullptr); - SetContext(sec_ctx); - } - sec_ctx->auth_context = args_.auth_context; - - auto* host = - call_args.client_initial_metadata->get_pointer(HttpAuthorityMetadata()); - if (host == nullptr) { - return next_promise_factory(std::move(call_args)); - } - return TrySeq( - args_.security_connector->CheckCallHost(host->as_string_view(), - args_.auth_context.get()), - [this, call_args = std::move(call_args)]() mutable { - return GetCallCredsMetadata(std::move(call_args)); - }, - next_promise_factory); -} - -absl::StatusOr> -LegacyClientAuthFilter::Create(const ChannelArgs& args, ChannelFilter::Args) { - auto* sc = args.GetObject(); - if (sc == nullptr) { - return absl::InvalidArgumentError( - "Security connector missing from client auth filter args"); - } - auto* auth_context = args.GetObject(); - if (auth_context == nullptr) { - return absl::InvalidArgumentError( - "Auth context missing from client auth filter args"); - } - return std::make_unique( - sc->RefAsSubclass(), - auth_context->Ref()); -} - -const grpc_channel_filter LegacyClientAuthFilter::kFilter = - MakePromiseBasedFilter(); - } // namespace grpc_core diff --git a/deps/grpc/src/core/filter/filter_args.h b/deps/grpc/src/core/filter/filter_args.h index 7f693169e11..e4d4a9a5804 100644 --- a/deps/grpc/src/core/filter/filter_args.h +++ b/deps/grpc/src/core/filter/filter_args.h @@ -31,23 +31,18 @@ class FilterArgs { grpc_channel_element* channel_element, size_t (*channel_stack_filter_instance_number)( grpc_channel_stack*, grpc_channel_element*), - const Blackboard* old_blackboard = nullptr, - Blackboard* new_blackboard = nullptr) + const Blackboard* blackboard = nullptr) : impl_(ChannelStackBased{channel_stack, channel_element, channel_stack_filter_instance_number}), - old_blackboard_(old_blackboard), - new_blackboard_(new_blackboard) {} + blackboard_(blackboard) {} // While we're moving to call-v3 we need to have access to // grpc_channel_stack & friends here. That means that we can't rely on this // type signature from interception_chain.h, which means that we need a way // of constructing this object without naming it ===> implicit construction. // TODO(ctiller): remove this once we're fully on call-v3 // NOLINTNEXTLINE(google-explicit-constructor) - FilterArgs(size_t instance_id, const Blackboard* old_blackboard = nullptr, - Blackboard* new_blackboard = nullptr) - : impl_(V3Based{instance_id}), - old_blackboard_(old_blackboard), - new_blackboard_(new_blackboard) {} + FilterArgs(size_t instance_id, const Blackboard* blackboard = nullptr) + : impl_(V3Based{instance_id}), blackboard_(blackboard) {} ABSL_DEPRECATED("Direct access to channel stack is deprecated") grpc_channel_stack* channel_stack() const { @@ -71,19 +66,11 @@ class FilterArgs { [](const V3Based& v3) { return v3.instance_id; }); } - // If a filter state object of type T exists for key from a previous - // filter stack, retains it for the new filter stack we're constructing. - // Otherwise, invokes create_func() to create a new filter state - // object for the new filter stack. Returns the new filter state object. + // Gets the filter state associated with a particular type and key. template - RefCountedPtr GetOrCreateState( - const std::string& key, - absl::FunctionRef()> create_func) { - RefCountedPtr state; - if (old_blackboard_ != nullptr) state = old_blackboard_->Get(key); - if (state == nullptr) state = create_func(); - if (new_blackboard_ != nullptr) new_blackboard_->Set(key, state); - return state; + RefCountedPtr GetState(const std::string& key) const { + if (blackboard_ == nullptr) return nullptr; + return blackboard_->Get(key); } private: @@ -103,8 +90,7 @@ class FilterArgs { using Impl = std::variant; Impl impl_; - const Blackboard* old_blackboard_ = nullptr; - Blackboard* new_blackboard_ = nullptr; + const Blackboard* blackboard_ = nullptr; }; } // namespace grpc_core diff --git a/deps/grpc/src/core/handshaker/handshaker.cc b/deps/grpc/src/core/handshaker/handshaker.cc index fe11b205c3a..48c3c4783b7 100644 --- a/deps/grpc/src/core/handshaker/handshaker.cc +++ b/deps/grpc/src/core/handshaker/handshaker.cc @@ -104,6 +104,16 @@ void HandshakeManager::DoHandshake( args_.args = channel_args; args_.event_engine = args_.args.GetObject(); args_.acceptor = acceptor; + // Add a channelz trace that we're performing a handshake. + // Note that we only commit this to the log if we see an error - otherwise + // it's ephemeral and is cleaned up when refs to it are released. + auto channelz_node = args_.args.GetObjectRef(); + args_.trace_node = channelz::TraceNode( + channelz_node.get() == nullptr + ? channelz::ChannelTrace::Node() + : channelz_node->NewTraceNode("Handshake connection"), + handshaker_trace, + [this]() { return absl::StrFormat("handshake manager %p: ", this); }); if (acceptor != nullptr && acceptor->external_connection && acceptor->pending_data != nullptr) { grpc_slice_buffer_swap(args_.read_buffer.c_slice_buffer(), @@ -125,14 +135,12 @@ void HandshakeManager::DoHandshake( void HandshakeManager::Shutdown(absl::Status error) { MutexLock lock(&mu_); if (!is_shutdown_) { - GRPC_TRACE_LOG(handshaker, INFO) - << "handshake_manager " << this << ": Shutdown() called: " << error; + GRPC_CHANNELZ_LOG(args_.trace_node) << "Shutdown called: " << error; is_shutdown_ = true; // Shutdown the handshaker that's currently in progress, if any. if (index_ > 0) { - GRPC_TRACE_LOG(handshaker, INFO) - << "handshake_manager " << this - << ": shutting down handshaker at index " << index_ - 1; + GRPC_CHANNELZ_LOG(args_.trace_node) + << "Shutting down handshaker at index " << (index_ - 1); handshakers_[index_ - 1]->Shutdown(std::move(error)); } } @@ -140,7 +148,7 @@ void HandshakeManager::Shutdown(absl::Status error) { void HandshakeManager::CallNextHandshakerLocked(absl::Status error) { GRPC_TRACE_LOG(handshaker, INFO) - << "handshake_manager " << this << ": error=" << error + << "CallNextHandshakerLocked: error=" << error << " shutdown=" << is_shutdown_ << " index=" << index_ << ", args=" << HandshakerArgsString(&args_); CHECK(index_ <= handshakers_.size()); @@ -153,10 +161,13 @@ void HandshakeManager::CallNextHandshakerLocked(absl::Status error) { error = GRPC_ERROR_CREATE("handshaker shutdown"); args_.endpoint.reset(); } - GRPC_TRACE_LOG(handshaker, INFO) << "handshake_manager " << this - << ": handshaking complete -- scheduling " - "on_handshake_done with error=" - << error; + // Since there was a handshaking error, commit this node with the reason. + // This will make it available for inspection after the handshaker + // completes. + if (!error.ok()) { + GRPC_CHANNELZ_LOG(args_.trace_node) << "Failed with error: " << error; + } + args_.trace_node.Commit(); // Cancel deadline timer, since we're invoking the on_handshake_done // callback now. args_.event_engine->Cancel(deadline_timer_handle_); @@ -174,10 +185,8 @@ void HandshakeManager::CallNextHandshakerLocked(absl::Status error) { } // Call the next handshaker. auto handshaker = handshakers_[index_]; - GRPC_TRACE_LOG(handshaker, INFO) - << "handshake_manager " << this << ": calling handshaker " - << handshaker->name() << " [" << handshaker.get() << "] at index " - << index_; + GRPC_CHANNELZ_LOG(args_.trace_node) + << " calling handshaker " << handshaker->name() << " at index " << index_; ++index_; handshaker->DoHandshake(&args_, [self = Ref()](absl::Status error) mutable { MutexLock lock(&self->mu_); diff --git a/deps/grpc/src/core/handshaker/handshaker.h b/deps/grpc/src/core/handshaker/handshaker.h index 251ec6bf7cc..028b297fe59 100644 --- a/deps/grpc/src/core/handshaker/handshaker.h +++ b/deps/grpc/src/core/handshaker/handshaker.h @@ -28,6 +28,7 @@ #include "absl/base/thread_annotations.h" #include "absl/container/inlined_vector.h" +#include "src/core/channelz/channelz.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" @@ -78,6 +79,8 @@ struct HandshakerArgs { // TODO(roth): Make this go away somehow as part of the EventEngine // migration? grpc_tcp_server_acceptor* acceptor = nullptr; + // Channelz trace node for the current handshaker + channelz::TraceNode trace_node; }; /// diff --git a/deps/grpc/src/core/handshaker/http_connect/http_connect_handshaker.cc b/deps/grpc/src/core/handshaker/http_connect/http_connect_handshaker.cc index 8930eeb3867..b902041de30 100644 --- a/deps/grpc/src/core/handshaker/http_connect/http_connect_handshaker.cc +++ b/deps/grpc/src/core/handshaker/http_connect/http_connect_handshaker.cc @@ -318,12 +318,14 @@ void HttpConnectHandshaker::DoHandshake( gpr_free(header_strings); // Take a new ref to be held by the write callback. Ref().release(); + grpc_event_engine::experimental::EventEngine::Endpoint::WriteArgs write_args; + write_args.set_max_frame_size(INT_MAX); grpc_endpoint_write( args->endpoint.get(), write_buffer_.c_slice_buffer(), GRPC_CLOSURE_INIT(&on_write_done_scheduler_, &HttpConnectHandshaker::OnWriteDoneScheduler, this, grpc_schedule_on_exec_ctx), - nullptr, /*max_frame_size=*/INT_MAX); + std::move(write_args)); } HttpConnectHandshaker::HttpConnectHandshaker() { diff --git a/deps/grpc/src/core/handshaker/security/legacy_secure_endpoint.cc b/deps/grpc/src/core/handshaker/security/legacy_secure_endpoint.cc index 1e2aa3ecc57..c20b84aa3d0 100644 --- a/deps/grpc/src/core/handshaker/security/legacy_secure_endpoint.cc +++ b/deps/grpc/src/core/handshaker/security/legacy_secure_endpoint.cc @@ -397,8 +397,9 @@ static void on_write(void* user_data, grpc_error_handle error) { }); } -static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg, int max_frame_size) { +static void endpoint_write( + grpc_endpoint* secure_ep, grpc_slice_buffer* slices, grpc_closure* cb, + grpc_event_engine::experimental::EventEngine::Endpoint::WriteArgs args) { GRPC_LATENT_SEE_INNER_SCOPE("secure_endpoint write"); unsigned i; tsi_result result = TSI_OK; @@ -427,10 +428,10 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, // tsi_zero_copy_grpc_protector_protect on each chunk. This ensures that // the protector cannot create frames larger than the specified // max_frame_size. - while (slices->length > static_cast(max_frame_size) && + while (slices->length > static_cast(args.max_frame_size()) && result == TSI_OK) { grpc_slice_buffer_move_first(slices, - static_cast(max_frame_size), + static_cast(args.max_frame_size()), &ep->protector_staging_buffer); result = tsi_zero_copy_grpc_protector_protect( ep->zero_copy_protector, &ep->protector_staging_buffer, @@ -523,7 +524,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, SECURE_ENDPOINT_REF(ep, "write"); ep->write_cb = cb; grpc_endpoint_write(ep->wrapped_ep.get(), &ep->output_buffer, &ep->on_write, - arg, max_frame_size); + std::move(args)); } static void endpoint_destroy(grpc_endpoint* secure_ep) { diff --git a/deps/grpc/src/core/handshaker/security/secure_endpoint.cc b/deps/grpc/src/core/handshaker/security/secure_endpoint.cc index b006c1f5673..1520300314d 100644 --- a/deps/grpc/src/core/handshaker/security/secure_endpoint.cc +++ b/deps/grpc/src/core/handshaker/security/secure_endpoint.cc @@ -30,16 +30,19 @@ #include #include +#include #include #include #include #include +#include #include "absl/base/thread_annotations.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "absl/status/status.h" #include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/experiments/experiments.h" #include "src/core/lib/iomgr/closure.h" @@ -183,6 +186,10 @@ class FrameProtector : public RefCounted { absl::Status Unprotect(absl::Status read_status) ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_) { + if (shutdown_) { + return absl::CancelledError("secure endpoint shutdown"); + } + GRPC_LATENT_SEE_INNER_SCOPE("unprotect"); bool keep_looping = false; tsi_result result = TSI_OK; @@ -312,6 +319,8 @@ class FrameProtector : public RefCounted { tsi_result Protect(grpc_slice_buffer* slices, int max_frame_size) ABSL_EXCLUSIVE_LOCKS_REQUIRED(write_mu_) { + if (shutdown_) return TSI_FAILED_PRECONDITION; + GRPC_LATENT_SEE_INNER_SCOPE("protect"); uint8_t* cur = GRPC_SLICE_START_PTR(write_staging_buffer_); uint8_t* end = GRPC_SLICE_END_PTR(write_staging_buffer_); @@ -414,7 +423,10 @@ class FrameProtector : public RefCounted { return &output_buffer_; } - void Shutdown() { memory_owner_.Reset(); } + void Shutdown() { + shutdown_ = true; + memory_owner_.Reset(); + } private: struct tsi_frame_protector* const protector_; @@ -436,6 +448,7 @@ class FrameProtector : public RefCounted { std::atomic has_posted_reclaimer_{false}; int min_progress_size_ = 1; SliceBuffer protector_staging_buffer_; + bool shutdown_ = false; }; } // namespace } // namespace grpc_core @@ -567,14 +580,15 @@ static void on_write(void* user_data, grpc_error_handle error) { }); } -static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg, int max_frame_size) { +static void endpoint_write( + grpc_endpoint* secure_ep, grpc_slice_buffer* slices, grpc_closure* cb, + grpc_event_engine::experimental::EventEngine::Endpoint::WriteArgs args) { GRPC_LATENT_SEE_INNER_SCOPE("secure_endpoint write"); secure_endpoint* ep = reinterpret_cast(secure_ep); tsi_result result; { grpc_core::MutexLock lock(ep->frame_protector.write_mu()); - result = ep->frame_protector.Protect(slices, max_frame_size); + result = ep->frame_protector.Protect(slices, args.max_frame_size()); } if (result != TSI_OK) { @@ -591,7 +605,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, ep->write_cb = cb; grpc_endpoint_write(ep->wrapped_ep.get(), ep->frame_protector.output_buffer()->c_slice_buffer(), - &ep->on_write, arg, max_frame_size); + &ep->on_write, std::move(args)); } static void endpoint_destroy(grpc_endpoint* secure_ep) { @@ -692,21 +706,59 @@ class SecureEndpoint final : public EventEngine::Endpoint { return impl_->QueryExtension(id); } - std::vector AllWriteMetrics() override { - return impl_->AllWriteMetrics(); - } - - std::optional GetMetricName(size_t key) override { - return impl_->GetMetricName(key); - } - - std::optional GetMetricKey(absl::string_view name) override { - return impl_->GetMetricKey(name); + std::shared_ptr GetTelemetryInfo() const override { + return std::make_shared(impl_->GetTelemetryInfo()); } private: class Impl : public grpc_core::RefCounted { public: + class TelemetryInfo : public EventEngine::Endpoint::TelemetryInfo { + public: + explicit TelemetryInfo( + std::shared_ptr + wrapped_telemetry_info) + : wrapped_telemetry_info_(std::move(wrapped_telemetry_info)) {} + + std::vector AllWriteMetrics() const override { + return wrapped_telemetry_info_ + ? wrapped_telemetry_info_->AllWriteMetrics() + : std::vector{}; + } + + std::optional GetMetricName( + size_t key) const override { + return wrapped_telemetry_info_ + ? wrapped_telemetry_info_->GetMetricName(key) + : std::nullopt; + } + + std::optional GetMetricKey( + absl::string_view name) const override { + return wrapped_telemetry_info_ + ? wrapped_telemetry_info_->GetMetricKey(name) + : std::nullopt; + } + + std::shared_ptr GetMetricsSet( + absl::Span keys) const override { + return wrapped_telemetry_info_ + ? wrapped_telemetry_info_->GetMetricsSet(keys) + : nullptr; + } + + std::shared_ptr GetFullMetricsSet() + const override { + return wrapped_telemetry_info_ + ? wrapped_telemetry_info_->GetFullMetricsSet() + : nullptr; + } + + private: + std::shared_ptr + wrapped_telemetry_info_; + }; + Impl(std::unique_ptr wrapped_ep, struct tsi_frame_protector* protector, @@ -837,16 +889,9 @@ class SecureEndpoint final : public EventEngine::Endpoint { frame_protector_.Shutdown(); } - virtual std::vector AllWriteMetrics() { - return wrapped_ep_->AllWriteMetrics(); - } - - virtual std::optional GetMetricName(size_t key) { - return wrapped_ep_->GetMetricName(key); - } - - virtual std::optional GetMetricKey(absl::string_view name) { - return wrapped_ep_->GetMetricKey(name); + std::shared_ptr GetTelemetryInfo() const { + return std::make_shared( + wrapped_ep_->GetTelemetryInfo()); } private: diff --git a/deps/grpc/src/core/handshaker/security/security_handshaker.cc b/deps/grpc/src/core/handshaker/security/security_handshaker.cc index 3bca02fcc75..843f62501c4 100644 --- a/deps/grpc/src/core/handshaker/security/security_handshaker.cc +++ b/deps/grpc/src/core/handshaker/security/security_handshaker.cc @@ -373,13 +373,16 @@ grpc_error_handle SecurityHandshaker::OnHandshakeNextDoneLocked( outgoing_.Clear(); outgoing_.Append(Slice::FromCopiedBuffer( reinterpret_cast(bytes_to_send), bytes_to_send_size)); + grpc_event_engine::experimental::EventEngine::Endpoint::WriteArgs + write_args; + write_args.set_max_frame_size(INT_MAX); grpc_endpoint_write( args_->endpoint.get(), outgoing_.c_slice_buffer(), NewClosure( [self = RefAsSubclass()](absl::Status status) { self->OnHandshakeDataSentToPeerFnScheduler(std::move(status)); }), - nullptr, /*max_frame_size=*/INT_MAX); + std::move(write_args)); } else if (handshaker_result == nullptr) { // There is nothing to send, but need to read from peer. grpc_endpoint_read( diff --git a/deps/grpc/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc b/deps/grpc/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc index 433ed2b061f..d9dada97db2 100644 --- a/deps/grpc/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +++ b/deps/grpc/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc @@ -119,11 +119,17 @@ void TCPConnectHandshaker::Shutdown(absl::Status /*error*/) { void TCPConnectHandshaker::DoHandshake( HandshakerArgs* args, absl::AnyInvocable on_handshake_done) { + // If the endpoint already exists, skip the TCP connection step. + // In this case, the handshaker becomes a no-op, it simply completes the + // handshake successfully without performing any action. + if (args->endpoint != nullptr) { + InvokeOnHandshakeDone(args, std::move(on_handshake_done), absl::OkStatus()); + return; + } { MutexLock lock(&mu_); on_handshake_done_ = std::move(on_handshake_done); } - CHECK_EQ(args->endpoint.get(), nullptr); args_ = args; absl::string_view resolved_address_text = args->args.GetString(GRPC_ARG_TCP_HANDSHAKER_RESOLVED_ADDRESS).value(); diff --git a/deps/grpc/src/core/lib/channel/channel_args.cc b/deps/grpc/src/core/lib/channel/channel_args.cc index a2c6ba42261..88faeadee3f 100644 --- a/deps/grpc/src/core/lib/channel/channel_args.cc +++ b/deps/grpc/src/core/lib/channel/channel_args.cc @@ -291,6 +291,21 @@ absl::string_view ChannelArgs::Value::ToString( return backing_strings.back(); } +channelz::PropertyList ChannelArgs::ToPropertyList() const { + channelz::PropertyList result; + args_.ForEach( + [&result](const RefCountedStringValue& key, const Value& value) { + if (auto i = value.GetIfInt(); i.has_value()) { + result.Set(key.as_string_view(), *i); + } else if (auto s = value.GetIfString(); s != nullptr) { + result.Set(key.as_string_view(), s->as_string_view()); + } else if (auto p = value.GetIfPointer(); p != nullptr) { + result.Set(key.as_string_view(), "POINTER"); + } + }); + return result; +} + std::string ChannelArgs::ToString() const { std::vector strings; std::list backing_strings; diff --git a/deps/grpc/src/core/lib/channel/channel_args.h b/deps/grpc/src/core/lib/channel/channel_args.h index 3cca824bd06..0184ead9fb5 100644 --- a/deps/grpc/src/core/lib/channel/channel_args.h +++ b/deps/grpc/src/core/lib/channel/channel_args.h @@ -35,6 +35,7 @@ #include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" +#include "src/core/channelz/property_list.h" #include "src/core/lib/surface/channel_stack_type.h" #include "src/core/util/avl.h" #include "src/core/util/debug_location.h" @@ -507,6 +508,8 @@ class ChannelArgs { GRPC_MUST_USE_RESULT ChannelArgs Remove(absl::string_view name) const; bool Contains(absl::string_view name) const; + channelz::PropertyList ToPropertyList() const; + GRPC_MUST_USE_RESULT ChannelArgs RemoveAllKeysWithPrefix(absl::string_view prefix) const; diff --git a/deps/grpc/src/core/lib/channel/channel_stack.cc b/deps/grpc/src/core/lib/channel/channel_stack.cc index 82de1acf554..58d5d130fe1 100644 --- a/deps/grpc/src/core/lib/channel/channel_stack.cc +++ b/deps/grpc/src/core/lib/channel/channel_stack.cc @@ -26,6 +26,7 @@ #include "absl/log/check.h" #include "absl/log/log.h" +#include "src/core/channelz/property_list.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_fwd.h" #include "src/core/lib/surface/channel_init.h" @@ -114,8 +115,7 @@ grpc_error_handle grpc_channel_stack_init( int initial_refs, grpc_iomgr_cb_func destroy, void* destroy_arg, const grpc_channel_filter** filters, size_t filter_count, const grpc_core::ChannelArgs& channel_args, const char* name, - grpc_channel_stack* stack, const grpc_core::Blackboard* old_blackboard, - grpc_core::Blackboard* new_blackboard) { + grpc_channel_stack* stack, const grpc_core::Blackboard* blackboard) { if (GRPC_TRACE_FLAG_ENABLED(channel_stack)) { LOG(INFO) << "CHANNEL_STACK: init " << name; for (size_t i = 0; i < filter_count; i++) { @@ -144,8 +144,7 @@ grpc_error_handle grpc_channel_stack_init( sizeof(grpc_channel_element)); // init per-filter data - args.old_blackboard = old_blackboard; - args.new_blackboard = new_blackboard; + args.blackboard = blackboard; grpc_error_handle first_error; for (i = 0; i < filter_count; i++) { args.channel_stack = stack; @@ -177,28 +176,28 @@ grpc_error_handle grpc_channel_stack_init( } void grpc_channel_stack::ChannelStackDataSource::AddData( - grpc_core::channelz::DataSink& sink) { - using grpc_core::Json; - Json::Object output; - output["type"] = Json::FromString("v1"); - Json::Array elements; + grpc_core::channelz::DataSink sink) { grpc_channel_stack* channel_stack = reinterpret_cast( reinterpret_cast(this) - offsetof(grpc_channel_stack, channelz_data_source)); - output["call_stack_size"] = Json::FromNumber(channel_stack->call_stack_size); - grpc_channel_element* elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); - elements.reserve(channel_stack->count); - for (size_t i = 0; i < channel_stack->count; i++) { - grpc_channel_element& e = elems[i]; - Json::Object element; - element["type"] = Json::FromString(std::string(e.filter->name.name())); - element["call_data_size"] = Json::FromNumber(e.filter->sizeof_call_data); - element["channel_data_size"] = - Json::FromNumber(e.filter->sizeof_channel_data); - elements.emplace_back(Json::FromObject(std::move(element))); - } - output["elements"] = Json::FromArray(std::move(elements)); - sink.AddAdditionalInfo("channelStack", std::move(output)); + sink.AddData( + "channel_stack", + grpc_core::channelz::PropertyList() + .Set("type", "v1") + .Set("elements", [channel_stack]() { + grpc_core::channelz::PropertyTable elements; + grpc_channel_element* elems = + CHANNEL_ELEMS_FROM_STACK(channel_stack); + for (size_t i = 0; i < channel_stack->count; i++) { + grpc_channel_element& e = elems[i]; + elements.AppendRow( + grpc_core::channelz::PropertyList() + .Set("type", e.filter->name.name()) + .Set("call_data_size", e.filter->sizeof_call_data) + .Set("channel_data_size", e.filter->sizeof_channel_data)); + } + return elements; + }())); } void grpc_channel_stack_destroy(grpc_channel_stack* stack) { diff --git a/deps/grpc/src/core/lib/channel/channel_stack.h b/deps/grpc/src/core/lib/channel/channel_stack.h index 859431daf7f..01045d95527 100644 --- a/deps/grpc/src/core/lib/channel/channel_stack.h +++ b/deps/grpc/src/core/lib/channel/channel_stack.h @@ -75,8 +75,7 @@ struct grpc_channel_element_args { grpc_core::ChannelArgs channel_args; int is_first; int is_last; - const grpc_core::Blackboard* old_blackboard; - grpc_core::Blackboard* new_blackboard; + const grpc_core::Blackboard* blackboard; }; struct grpc_call_element_args { grpc_call_stack* call_stack; @@ -190,9 +189,13 @@ struct grpc_channel_stack { class ChannelStackDataSource final : public grpc_core::channelz::DataSource { public: - using grpc_core::channelz::DataSource::DataSource; - ~ChannelStackDataSource() { ResetDataSource(); } - void AddData(grpc_core::channelz::DataSink& sink) override; + explicit ChannelStackDataSource( + grpc_core::RefCountedPtr node) + : DataSource(std::move(node)) { + SourceConstructed(); + } + ~ChannelStackDataSource() { SourceDestructing(); } + void AddData(grpc_core::channelz::DataSink sink) override; }; grpc_core::ManualConstructor channelz_data_source; @@ -269,8 +272,7 @@ grpc_error_handle grpc_channel_stack_init( const grpc_channel_filter** filters, size_t filter_count, const grpc_core::ChannelArgs& args, const char* name, grpc_channel_stack* stack, - const grpc_core::Blackboard* old_blackboard = nullptr, - grpc_core::Blackboard* new_blackboard = nullptr); + const grpc_core::Blackboard* blackboard = nullptr); // Destroy a channel stack void grpc_channel_stack_destroy(grpc_channel_stack* stack); diff --git a/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.cc b/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.cc index 3f2bec6757b..0b3874ed514 100644 --- a/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.cc +++ b/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.cc @@ -75,7 +75,7 @@ ChannelStackBuilderImpl::Build() { gpr_free(stk); }, channel_stack, stack.data(), stack.size(), channel_args(), name(), - channel_stack, old_blackboard_, new_blackboard_); + channel_stack, blackboard_); if (!error.ok()) { grpc_channel_stack_destroy(channel_stack); diff --git a/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.h b/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.h index 6de06ebba73..d68421b629c 100644 --- a/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.h +++ b/deps/grpc/src/core/lib/channel/channel_stack_builder_impl.h @@ -35,11 +35,7 @@ class ChannelStackBuilderImpl final : public ChannelStackBuilder { public: using ChannelStackBuilder::ChannelStackBuilder; - void SetBlackboards(const Blackboard* old_blackboard, - Blackboard* new_blackboard) { - old_blackboard_ = old_blackboard; - new_blackboard_ = new_blackboard; - } + void SetBlackboard(const Blackboard* blackboard) { blackboard_ = blackboard; } // Build the channel stack. // After success, *result holds the new channel stack, @@ -49,8 +45,7 @@ class ChannelStackBuilderImpl final : public ChannelStackBuilder { absl::StatusOr> Build() override; private: - const Blackboard* old_blackboard_ = nullptr; - Blackboard* new_blackboard_ = nullptr; + const Blackboard* blackboard_ = nullptr; }; } // namespace grpc_core diff --git a/deps/grpc/src/core/lib/channel/promise_based_filter.h b/deps/grpc/src/core/lib/channel/promise_based_filter.h index 3f98c56c259..9ebf87f404f 100644 --- a/deps/grpc/src/core/lib/channel/promise_based_filter.h +++ b/deps/grpc/src/core/lib/channel/promise_based_filter.h @@ -1979,11 +1979,11 @@ struct ChannelFilterWithFlagsMethods { static absl::Status InitChannelElem(grpc_channel_element* elem, grpc_channel_element_args* args) { CHECK(args->is_last == ((kFlags & kFilterIsLast) != 0)); - auto status = F::Create( - args->channel_args, - ChannelFilter::Args(args->channel_stack, elem, - grpc_channel_stack_filter_instance_number, - args->old_blackboard, args->new_blackboard)); + auto status = + F::Create(args->channel_args, + ChannelFilter::Args(args->channel_stack, elem, + grpc_channel_stack_filter_instance_number, + args->blackboard)); if (!status.ok()) { new (elem->channel_data) F*(nullptr); return absl_status_to_grpc_error(status.status()); diff --git a/deps/grpc/src/core/lib/debug/trace_impl.h b/deps/grpc/src/core/lib/debug/trace_impl.h index 5d43e103433..82e6ce18f9c 100644 --- a/deps/grpc/src/core/lib/debug/trace_impl.h +++ b/deps/grpc/src/core/lib/debug/trace_impl.h @@ -75,7 +75,6 @@ class TraceFlag { value_.store(enabled, std::memory_order_relaxed); } - TraceFlag* next_tracer_; const char* const name_; std::atomic value_; }; diff --git a/deps/grpc/src/core/lib/event_engine/ares_resolver.cc b/deps/grpc/src/core/lib/event_engine/ares_resolver.cc index b34b1448641..7fa1e1c7feb 100644 --- a/deps/grpc/src/core/lib/event_engine/ares_resolver.cc +++ b/deps/grpc/src/core/lib/event_engine/ares_resolver.cc @@ -15,6 +15,7 @@ #include +#include #include #include @@ -53,13 +54,14 @@ #include #include "absl/functional/any_invocable.h" -#include "absl/hash/hash.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "absl/strings/match.h" #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "absl/strings/substitute.h" #include "src/core/config/config_vars.h" #include "src/core/lib/address_utils/parse_address.h" #include "src/core/lib/address_utils/sockaddr_utils.h" @@ -67,7 +69,6 @@ #include "src/core/lib/event_engine/grpc_polled_fd.h" #include "src/core/lib/event_engine/time_util.h" #include "src/core/lib/iomgr/resolved_address.h" -#include "src/core/lib/iomgr/sockaddr.h" #include "src/core/util/debug_location.h" #include "src/core/util/host_port.h" #include "src/core/util/orphanable.h" @@ -107,9 +108,9 @@ absl::Status AresStatusToAbslStatus(int status, absl::string_view error_msg) { constexpr EventEngine::Duration kAresBackupPollAlarmDuration = std::chrono::seconds(1); -bool IsIpv6LoopbackAvailable() { +bool AresIsIpv6LoopbackAvailable() { #ifdef GRPC_POSIX_SOCKET_ARES_EV_DRIVER - return PosixSocketWrapper::IsIpv6LoopbackAvailable(); + return IsIpv6LoopbackAvailable(); #elif defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) // TODO(yijiem): implement this for Windows return true; @@ -189,73 +190,118 @@ struct HostnameQueryArg : public QueryArg { std::vector result; }; -} // namespace - -absl::StatusOr> -AresResolver::CreateAresResolver( - absl::string_view dns_server, - std::unique_ptr polled_fd_factory, - std::shared_ptr event_engine) { +absl::Status InitAresChannel(absl::string_view dns_server, + GrpcPolledFdFactory& polled_fd_factory, + ares_channel* channel) { ares_options opts = {}; opts.flags |= ARES_FLAG_STAYOPEN; if (g_event_engine_grpc_ares_test_only_force_tcp) { opts.flags |= ARES_FLAG_USEVC; } - ares_channel channel; - int status = ares_init_options(&channel, &opts, ARES_OPT_FLAGS); + int status = ares_init_options(channel, &opts, ARES_OPT_FLAGS); if (status != ARES_SUCCESS) { LOG(ERROR) << "ares_init_options failed, status: " << status; return AresStatusToAbslStatus( status, absl::StrCat("Failed to init c-ares channel: ", ares_strerror(status))); } - event_engine_grpc_ares_test_only_inject_config(&channel); - polled_fd_factory->ConfigureAresChannelLocked(channel); + event_engine_grpc_ares_test_only_inject_config(channel); + polled_fd_factory.ConfigureAresChannelLocked(*channel); if (!dns_server.empty()) { - absl::Status status = SetRequestDNSServer(dns_server, &channel); + absl::Status status = SetRequestDNSServer(dns_server, channel); if (!status.ok()) { return status; } } - return grpc_core::MakeOrphanable( - std::move(polled_fd_factory), std::move(event_engine), channel); + return absl::OkStatus(); +} + +} // namespace + +// AresResolver::ReinitHandle +#ifdef GRPC_ENABLE_FORK_SUPPORT + +AresResolver::ReinitHandle::ReinitHandle(AresResolver* resolver) + : resolver_(resolver) {} + +void AresResolver::ReinitHandle::OnResolverGone() { + grpc_core::MutexLock lock(&mutex_); + resolver_ = nullptr; +} + +void AresResolver::ReinitHandle::Reset(const absl::Status& status) { + grpc_core::MutexLock lock(&mutex_); + if (resolver_ != nullptr) { + resolver_->Reset(status); + } +} + +void AresResolver::ReinitHandle::Restart() { + grpc_core::MutexLock lock(&mutex_); + if (resolver_ != nullptr) { + resolver_->Restart(); + } +} + +#endif // GRPC_ENABLE_FORK_SUPPORT + +// AresResolver + +absl::StatusOr> +AresResolver::CreateAresResolver( + absl::string_view dns_server, + std::unique_ptr polled_fd_factory, + std::shared_ptr event_engine) { + ares_channel channel; + absl::Status status = + InitAresChannel(dns_server, *polled_fd_factory, &channel); + if (!status.ok()) { + return status; + } + return grpc_core::MakeOrphanable(std::move(polled_fd_factory), + std::move(event_engine), + channel, dns_server); } AresResolver::AresResolver( std::unique_ptr polled_fd_factory, - std::shared_ptr event_engine, ares_channel channel) + std::shared_ptr event_engine, ares_channel channel, + absl::string_view dns_server) : RefCountedDNSResolverInterface( GRPC_TRACE_FLAG_ENABLED(cares_resolver) ? "AresResolver" : nullptr), channel_(channel), polled_fd_factory_(std::move(polled_fd_factory)), +#ifdef GRPC_ENABLE_FORK_SUPPORT + dns_server_(dns_server), +#endif // GRPC_ENABLE_FORK_SUPPORT event_engine_(std::move(event_engine)) { + (void)dns_server; // Used whether or not compiled with fork support polled_fd_factory_->Initialize(&mutex_, event_engine_.get()); } AresResolver::~AresResolver() { CHECK(fd_node_list_.empty()); CHECK(callback_map_.empty()); + CHECK_NE(channel_, nullptr); ares_destroy(channel_); } void AresResolver::Orphan() { +#ifdef GRPC_ENABLE_FORK_SUPPORT + // Do this before locking &mutex_ - ensures there will be no deadlock if + // resolver is being orphaned during fork. + { + grpc_core::MutexLock handle_lock(&reinit_handle_mu_); + if (reinit_handle_ != nullptr) { + reinit_handle_->OnResolverGone(); + } + } +#endif { grpc_core::MutexLock lock(&mutex_); shutting_down_ = true; - if (ares_backup_poll_alarm_handle_.has_value()) { - event_engine_->Cancel(*ares_backup_poll_alarm_handle_); - ares_backup_poll_alarm_handle_.reset(); - } - for (const auto& fd_node : fd_node_list_) { - if (!fd_node->already_shutdown) { - GRPC_TRACE_LOG(cares_resolver, INFO) - << "(EventEngine c-ares resolver) resolver: " << this - << " shutdown fd: " << fd_node->polled_fd->GetName(); - CHECK(fd_node->polled_fd->ShutdownLocked( - absl::CancelledError("AresResolver::Orphan"))); - fd_node->already_shutdown = true; - } - } + ShutdownLocked(absl::CancelledError("AresResolver::Orphan"), + "resolver orphaned"); } Unref(DEBUG_LOCATION, "Orphan"); } @@ -321,7 +367,8 @@ void AresResolver::LookupHostname( grpc_core::MutexLock lock(&mutex_); callback_map_.emplace(++id_, std::move(callback)); auto* resolver_arg = new HostnameQueryArg(this, id_, name, port); - if (IsIpv6LoopbackAvailable()) { + CHECK_NE(channel_, nullptr); + if (AresIsIpv6LoopbackAvailable()) { // Note that using AF_UNSPEC for both IPv6 and IPv4 queries does not work in // all cases, e.g. for localhost:<> it only gets back the IPv6 result (i.e. // ::1). @@ -368,6 +415,7 @@ void AresResolver::LookupSRV( grpc_core::MutexLock lock(&mutex_); callback_map_.emplace(++id_, std::move(callback)); auto* resolver_arg = new QueryArg(this, id_, host); + CHECK_NE(channel_, nullptr); ares_query(channel_, std::string(host).c_str(), ns_c_in, ns_t_srv, &AresResolver::OnSRVQueryDoneLocked, resolver_arg); CheckSocketsLocked(); @@ -403,6 +451,7 @@ void AresResolver::LookupTXT( grpc_core::MutexLock lock(&mutex_); callback_map_.emplace(++id_, std::move(callback)); auto* resolver_arg = new QueryArg(this, id_, host); + CHECK_NE(channel_, nullptr); ares_search(channel_, std::string(host).c_str(), ns_c_in, ns_t_txt, &AresResolver::OnTXTDoneLocked, resolver_arg); CheckSocketsLocked(); @@ -411,15 +460,17 @@ void AresResolver::LookupTXT( void AresResolver::CheckSocketsLocked() { FdNodeList new_list; - if (!shutting_down_) { + if (!shutting_down_ && channel_ != nullptr) { ares_socket_t socks[ARES_GETSOCK_MAXNUM] = {}; int socks_bitmask = ares_getsock(channel_, socks, ARES_GETSOCK_MAXNUM); for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) { if (ARES_GETSOCK_READABLE(socks_bitmask, i) || ARES_GETSOCK_WRITABLE(socks_bitmask, i)) { - auto iter = std::find_if( - fd_node_list_.begin(), fd_node_list_.end(), - [sock = socks[i]](const auto& node) { return node->as == sock; }); + auto iter = std::find_if(fd_node_list_.begin(), fd_node_list_.end(), + [sock = socks[i]](const auto& node) { + return node->as == sock && + node->polled_fd->IsCurrent(); + }); if (iter == fd_node_list_.end()) { GRPC_TRACE_LOG(cares_resolver, INFO) << "(EventEngine c-ares resolver) resolver:" << this @@ -530,14 +581,16 @@ void AresResolver::OnReadable(FdNode* fd_node, absl::Status status) { GRPC_TRACE_LOG(cares_resolver, INFO) << "(EventEngine c-ares resolver) OnReadable: fd: " << fd_node->as << "; request: " << this << "; status: " << status; - if (status.ok() && !shutting_down_) { + if (status.ok() && !shutting_down_ && channel_ != nullptr) { ares_process_fd(channel_, fd_node->as, ARES_SOCKET_BAD); - } else { + } else if (fd_node->polled_fd->IsCurrent() && channel_ != nullptr) { // If error is not absl::OkStatus() or the resolution was cancelled, it // means the fd has been shutdown or timed out. The pending lookups made // on this request will be cancelled by the following ares_cancel(). The // remaining file descriptors in this request will be cleaned up in the // following Work() method. + // + // Nothing is done if the handle is not current. ares_cancel(channel_); } CheckSocketsLocked(); @@ -550,9 +603,9 @@ void AresResolver::OnWritable(FdNode* fd_node, absl::Status status) { GRPC_TRACE_LOG(cares_resolver, INFO) << "(EventEngine c-ares resolver) OnWritable: fd: " << fd_node->as << "; request:" << this << "; status: " << status; - if (status.ok() && !shutting_down_) { + if (status.ok() && !shutting_down_ && channel_ != nullptr) { ares_process_fd(channel_, ARES_SOCKET_BAD, fd_node->as); - } else { + } else if (fd_node->polled_fd->IsCurrent() && channel_ != nullptr) { // If error is not absl::OkStatus() or the resolution was cancelled, it // means the fd has been shutdown or timed out. The pending lookups made // on this request will be cancelled by the following ares_cancel(). The @@ -577,7 +630,7 @@ void AresResolver::OnAresBackupPollAlarm() { GRPC_TRACE_LOG(cares_resolver, INFO) << "(EventEngine c-ares resolver) request:" << this << " OnAresBackupPollAlarm shutting_down=" << shutting_down_; - if (!shutting_down_) { + if (!shutting_down_ && channel_ != nullptr) { for (const auto& fd_node : fd_node_list_) { if (!fd_node->already_shutdown) { GRPC_TRACE_LOG(cares_resolver, INFO) @@ -665,7 +718,10 @@ void AresResolver::OnHostbynameDoneLocked(void* arg, int status, if (hostname_qa->pending_requests == 0) { auto nh = ares_resolver->callback_map_.extract(hostname_qa->callback_map_id); - CHECK(!nh.empty()); + if (nh.empty()) { + delete hostname_qa; + return; + } CHECK(std::holds_alternative< EventEngine::DNSResolver::LookupHostnameCallback>(nh.mapped())); auto callback = std::get( @@ -692,7 +748,9 @@ void AresResolver::OnSRVQueryDoneLocked(void* arg, int status, int /*timeouts*/, std::unique_ptr qa(static_cast(arg)); auto* ares_resolver = qa->ares_resolver; auto nh = ares_resolver->callback_map_.extract(qa->callback_map_id); - CHECK(!nh.empty()); + if (nh.empty()) { + return; + } CHECK(std::holds_alternative( nh.mapped())); auto callback = std::get( @@ -753,7 +811,9 @@ void AresResolver::OnTXTDoneLocked(void* arg, int status, int /*timeouts*/, std::unique_ptr qa(static_cast(arg)); auto* ares_resolver = qa->ares_resolver; auto nh = ares_resolver->callback_map_.extract(qa->callback_map_id); - CHECK(!nh.empty()); + if (nh.empty()) { + return; + } CHECK(std::holds_alternative( nh.mapped())); auto callback = std::get( @@ -809,6 +869,65 @@ void AresResolver::OnTXTDoneLocked(void* arg, int status, int /*timeouts*/, }); } +#ifdef GRPC_ENABLE_FORK_SUPPORT + +std::weak_ptr AresResolver::GetReinitHandle() { + grpc_core::MutexLock lock(&reinit_handle_mu_); + if (reinit_handle_ == nullptr) { + reinit_handle_ = ReinitHandle::New(this); + } + return reinit_handle_; +} + +void AresResolver::Reset(const absl::Status& reason) { + auto self = RefIfNonZero(); + if (self == nullptr) { + return; + } + grpc_core::MutexLock lock(&mutex_); + for (auto& [_, callback] : callback_map_) { + event_engine_->Run( + [callback = std::move(callback), reason = reason]() mutable { + std::visit([&](auto& cb) { cb(reason); }, callback); + }); + } + callback_map_.clear(); + ShutdownLocked(reason, "resolver reset"); + CheckSocketsLocked(); + CHECK_NE(channel_, nullptr); + ares_destroy(channel_); + channel_ = nullptr; +} + +void AresResolver::Restart() { + grpc_core::MutexLock lock(&mutex_); + polled_fd_factory_ = polled_fd_factory_->NewEmptyInstance(); + polled_fd_factory_->Initialize(&mutex_, event_engine_.get()); + CHECK_EQ(channel_, nullptr); + absl::Status status = + InitAresChannel(dns_server_, *polled_fd_factory_, &channel_); + CHECK_OK(status); +} + +#endif // GRPC_ENABLE_FORK_SUPPORT + +void AresResolver::ShutdownLocked(const absl::Status& shutdown_status, + absl::string_view reason) { + if (ares_backup_poll_alarm_handle_.has_value()) { + event_engine_->Cancel(*ares_backup_poll_alarm_handle_); + ares_backup_poll_alarm_handle_.reset(); + } + for (const auto& fd_node : fd_node_list_) { + if (!fd_node->already_shutdown) { + GRPC_TRACE_LOG(cares_resolver, INFO) << absl::Substitute( + "(EventEngine c-ares resolver) resolver: $0 shutdown fd: $1 ($2)", + this, fd_node->polled_fd->GetName(), reason); + CHECK(fd_node->polled_fd->ShutdownLocked(shutdown_status)); + fd_node->already_shutdown = true; + } + } +} + } // namespace grpc_event_engine::experimental void noop_inject_channel_config(ares_channel* /*channel*/) {} diff --git a/deps/grpc/src/core/lib/event_engine/ares_resolver.h b/deps/grpc/src/core/lib/event_engine/ares_resolver.h index e49562adf47..4658163cb5c 100644 --- a/deps/grpc/src/core/lib/event_engine/ares_resolver.h +++ b/deps/grpc/src/core/lib/event_engine/ares_resolver.h @@ -19,7 +19,6 @@ #include #include "absl/status/status.h" -#include "src/core/lib/debug/trace.h" #if GRPC_ARES == 1 @@ -42,6 +41,32 @@ namespace grpc_event_engine::experimental { class AresResolver : public RefCountedDNSResolverInterface { public: +#ifdef GRPC_ENABLE_FORK_SUPPORT + // Handle to trigger reinitialization of this AresResolver instance after a + // fork(). Avoids global resolver management and POSIX-specific dependencies + // within AresResolver. + class ReinitHandle { + public: + static std::shared_ptr New(AresResolver* resolver) { + return std::shared_ptr(new ReinitHandle(resolver)); + } + + ReinitHandle(ReinitHandle&& other) = delete; + ReinitHandle(const ReinitHandle& other) = delete; + void OnResolverGone(); + // Clears resources (such as CARES handles) held by the associated resolver. + void Reset(const absl::Status& status); + // Reinitializes the associated resolver after Reset. + void Restart(); + + private: + explicit ReinitHandle(AresResolver* resolver); + + grpc_core::Mutex mutex_; + AresResolver* resolver_ ABSL_GUARDED_BY(&mutex_); + }; +#endif // GRPC_ENABLE_FORK_SUPPORT + static absl::StatusOr> CreateAresResolver(absl::string_view dns_server, std::unique_ptr polled_fd_factory, @@ -49,7 +74,8 @@ class AresResolver : public RefCountedDNSResolverInterface { // Do not instantiate directly -- use CreateAresResolver() instead. AresResolver(std::unique_ptr polled_fd_factory, - std::shared_ptr event_engine, ares_channel channel); + std::shared_ptr event_engine, ares_channel channel, + absl::string_view dns_server); ~AresResolver() override; void Orphan() override ABSL_LOCKS_EXCLUDED(mutex_); @@ -60,6 +86,9 @@ class AresResolver : public RefCountedDNSResolverInterface { absl::string_view name) ABSL_LOCKS_EXCLUDED(mutex_) override; void LookupTXT(EventEngine::DNSResolver::LookupTXTCallback callback, absl::string_view name) ABSL_LOCKS_EXCLUDED(mutex_) override; +#ifdef GRPC_ENABLE_FORK_SUPPORT + std::weak_ptr GetReinitHandle(); +#endif // GRPC_ENABLE_FORK_SUPPORT private: // A FdNode saves (not owns) a live socket/fd which c-ares creates, and owns a @@ -109,6 +138,17 @@ class AresResolver : public RefCountedDNSResolverInterface { static void OnTXTDoneLocked(void* arg, int status, int /*timeouts*/, unsigned char* buf, int len) ABSL_NO_THREAD_SAFETY_ANALYSIS; +#ifdef GRPC_ENABLE_FORK_SUPPORT + // Is executed on fork before the poller is restarted. Cleans up the resources + // from the previous generation. + void Reset(const absl::Status& reason); + // Is executed on fork after the poller is restarted. Makes the resolver + // usable once more. + void Restart(); +#endif // GRPC_ENABLE_FORK_SUPPORT + void ShutdownLocked(const absl::Status& shutdown_status, + absl::string_view reason) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); grpc_core::Mutex mutex_; bool shutting_down_ ABSL_GUARDED_BY(mutex_) = false; @@ -119,6 +159,12 @@ class AresResolver : public RefCountedDNSResolverInterface { std::optional ares_backup_poll_alarm_handle_ ABSL_GUARDED_BY(mutex_); std::unique_ptr polled_fd_factory_; +#ifdef GRPC_ENABLE_FORK_SUPPORT + std::string dns_server_; + grpc_core::Mutex reinit_handle_mu_; + std::shared_ptr reinit_handle_ + ABSL_GUARDED_BY(reinit_handle_mu_); +#endif // GRPC_ENABLE_FORK_SUPPORT std::shared_ptr event_engine_; }; diff --git a/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.cc b/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.cc index 83b1188a846..f93225b3646 100644 --- a/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.cc +++ b/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.cc @@ -31,6 +31,7 @@ #include "src/core/lib/event_engine/thread_pool/thread_pool.h" #include "src/core/lib/event_engine/utils.h" #include "src/core/util/crash.h" +#include "src/core/util/useful.h" #ifndef GRPC_CFSTREAM_MAX_THREADPOOL_SIZE #define GRPC_CFSTREAM_MAX_THREADPOOL_SIZE 16u @@ -58,7 +59,8 @@ struct CFEventEngine::Closure final : public EventEngine::Closure { CFEventEngine::CFEventEngine() : thread_pool_(MakeThreadPool(grpc_core::Clamp( - gpr_cpu_num_cores(), 2u, GRPC_CFSTREAM_MAX_THREADPOOL_SIZE))), + gpr_cpu_num_cores(), 2u, + static_cast(GRPC_CFSTREAM_MAX_THREADPOOL_SIZE)))), timer_manager_(thread_pool_) {} CFEventEngine::~CFEventEngine() { diff --git a/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.h b/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.h index 4e02d6edc57..b488460e152 100644 --- a/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.h +++ b/deps/grpc/src/core/lib/event_engine/cf_engine/cf_engine.h @@ -26,14 +26,11 @@ #include "src/core/lib/event_engine/posix_engine/lockfree_event.h" #include "src/core/lib/event_engine/posix_engine/posix_engine_closure.h" #include "src/core/lib/event_engine/posix_engine/timer_manager.h" -#include "src/core/lib/surface/init_internally.h" #include "src/core/util/sync.h" namespace grpc_event_engine::experimental { -class CFEventEngine : public EventEngine, - public Scheduler, - public grpc_core::KeepsGrpcInitialized { +class CFEventEngine : public EventEngine, public Scheduler { public: CFEventEngine(); ~CFEventEngine() override; diff --git a/deps/grpc/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h b/deps/grpc/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h index 7ffd15b54d9..517a5c2ba26 100644 --- a/deps/grpc/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +++ b/deps/grpc/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h @@ -124,12 +124,8 @@ class CFStreamEndpoint : public EventEngine::Endpoint { return impl_->GetLocalAddress(); } - std::vector AllWriteMetrics() override { return {}; } - std::optional GetMetricName(size_t) override { - return std::nullopt; - } - std::optional GetMetricKey(absl::string_view) override { - return std::nullopt; + std::shared_ptr GetTelemetryInfo() const override { + return nullptr; } public: diff --git a/deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc b/deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc new file mode 100644 index 00000000000..d890e8ff9f1 --- /dev/null +++ b/deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc @@ -0,0 +1,40 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/lib/event_engine/endpoint_channel_arg_wrapper.h" + +#include "src/core/util/useful.h" +namespace grpc_event_engine { +namespace experimental { + +EndpointChannelArgWrapper::EndpointChannelArgWrapper( + std::unique_ptr endpoint) + : endpoint_(std::move(endpoint)) {} + +std::unique_ptr +EndpointChannelArgWrapper::TakeEndpoint() { + return std::move(endpoint_); +} + +absl::string_view EndpointChannelArgWrapper::ChannelArgName() { + return "grpc.internal.subchannel_endpoint"; +} + +int EndpointChannelArgWrapper::ChannelArgsCompare( + const EndpointChannelArgWrapper* a, const EndpointChannelArgWrapper* b) { + return QsortCompare(a, b); +} + +} // namespace experimental +} // namespace grpc_event_engine diff --git a/deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h b/deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h new file mode 100644 index 00000000000..05c1f76046f --- /dev/null +++ b/deps/grpc/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h @@ -0,0 +1,60 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_ENDPOINT_CHANNEL_ARG_WRAPPER_H +#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_ENDPOINT_CHANNEL_ARG_WRAPPER_H + +#include + +#include + +#include "src/core/util/ref_counted.h" + +namespace grpc_event_engine { + +namespace experimental { + +/// Wrapper for EventEngine::Endpoint to enable storing it in channel args. +/// +/// This class encapsulates a `std::unique_ptr` so that +/// an already-connected endpoint can be passed through channel arguments. +/// This is useful when creating a channel with a pre-established connection, +/// such as when using `CreateChannelFromEndpoint()` or `CreateChannelFromFd()`. +/// +/// The wrapper provides: +/// - Ownership management via unique_ptr +/// - A static `ChannelArgName()` method to identify the channel arg +/// - A comparison function for use in channel args internals +/// +/// Note: This is intended for internal use only. +class EndpointChannelArgWrapper + : public grpc_core::RefCounted { + public: + explicit EndpointChannelArgWrapper( + std::unique_ptr endpoint); + + std::unique_ptr TakeEndpoint(); + + static absl::string_view ChannelArgName(); + static int ChannelArgsCompare(const EndpointChannelArgWrapper* a, + const EndpointChannelArgWrapper* b); + + private: + std::unique_ptr endpoint_; +}; + +} // namespace experimental +} // namespace grpc_event_engine + +#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_ENDPOINT_CHANNEL_ARG_WRAPPER_H diff --git a/deps/grpc/src/core/lib/event_engine/event_engine.cc b/deps/grpc/src/core/lib/event_engine/event_engine.cc index 80071162e14..30d34b0b598 100644 --- a/deps/grpc/src/core/lib/event_engine/event_engine.cc +++ b/deps/grpc/src/core/lib/event_engine/event_engine.cc @@ -15,9 +15,16 @@ #include #include "absl/strings/str_cat.h" +#include "src/core/telemetry/context_list_entry.h" namespace grpc_event_engine::experimental { +EventEngine::Endpoint::WriteArgs::~WriteArgs() { + if (google_specific_ != nullptr) { + delete reinterpret_cast(google_specific_); + } +} + const EventEngine::TaskHandle EventEngine::TaskHandle::kInvalid = {-1, -1}; const EventEngine::ConnectionHandle EventEngine::ConnectionHandle::kInvalid = { -1, -1}; diff --git a/deps/grpc/src/core/lib/event_engine/extensions/channelz.h b/deps/grpc/src/core/lib/event_engine/extensions/channelz.h index 963f3e82c9d..194e1568a69 100644 --- a/deps/grpc/src/core/lib/event_engine/extensions/channelz.h +++ b/deps/grpc/src/core/lib/event_engine/extensions/channelz.h @@ -34,19 +34,23 @@ class ChannelzExtension { void SetSocketNode( grpc_core::RefCountedPtr socket_node) { - data_source_ = - std::make_unique(std::move(socket_node), this); + data_source_.emplace(std::move(socket_node), this); } + protected: + void ShutdownChannelzExtension() { data_source_.reset(); } + private: class EndpointDataSource final : public grpc_core::channelz::DataSource { public: EndpointDataSource( grpc_core::RefCountedPtr socket_node, ChannelzExtension* ep) - : grpc_core::channelz::DataSource(std::move(socket_node)), ep_(ep) {} - ~EndpointDataSource() { ResetDataSource(); } - void AddData(grpc_core::channelz::DataSink& sink) override { + : grpc_core::channelz::DataSource(std::move(socket_node)), ep_(ep) { + SourceConstructed(); + } + ~EndpointDataSource() { SourceDestructing(); } + void AddData(grpc_core::channelz::DataSink sink) override { ep_->AddJson(sink); } @@ -54,7 +58,7 @@ class ChannelzExtension { ChannelzExtension* ep_; }; - std::unique_ptr data_source_; + std::optional data_source_; }; } // namespace grpc_event_engine::experimental diff --git a/deps/grpc/src/core/lib/event_engine/forkable.cc b/deps/grpc/src/core/lib/event_engine/forkable.cc deleted file mode 100644 index 012c2cce1ca..00000000000 --- a/deps/grpc/src/core/lib/event_engine/forkable.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2022 gRPC authors. -// -// 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. - -#include "src/core/lib/event_engine/forkable.h" - -#include - -#include "absl/log/check.h" - -#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK -#include -#endif - -#include -#include -#include - -#include "src/core/config/config_vars.h" -#include "src/core/lib/debug/trace.h" - -namespace grpc_event_engine::experimental { - -namespace { -bool IsForkEnabled() { - static bool enabled = grpc_core::ConfigVars::Get().EnableForkSupport(); - return enabled; -} -} // namespace - -void ObjectGroupForkHandler::RegisterForkable( - std::shared_ptr forkable, GRPC_UNUSED void (*prepare)(void), - GRPC_UNUSED void (*parent)(void), GRPC_UNUSED void (*child)(void)) { - if (IsForkEnabled()) { - CHECK(!is_forking_); - forkables_.emplace_back(forkable); -#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK - if (!std::exchange(registered_, true)) { - pthread_atfork(prepare, parent, child); - } -#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK - } -} - -void ObjectGroupForkHandler::Prefork() { - if (IsForkEnabled()) { - CHECK(!std::exchange(is_forking_, true)); - GRPC_TRACE_LOG(fork, INFO) << "PrepareFork"; - for (auto it = forkables_.begin(); it != forkables_.end();) { - auto shared = it->lock(); - if (shared) { - shared->PrepareFork(); - ++it; - } else { - it = forkables_.erase(it); - } - } - } -} - -void ObjectGroupForkHandler::PostforkParent() { - if (IsForkEnabled()) { - CHECK(is_forking_); - GRPC_TRACE_LOG(fork, INFO) << "PostforkParent"; - for (auto it = forkables_.begin(); it != forkables_.end();) { - auto shared = it->lock(); - if (shared) { - shared->PostforkParent(); - ++it; - } else { - it = forkables_.erase(it); - } - } - is_forking_ = false; - } -} - -void ObjectGroupForkHandler::PostforkChild() { - if (IsForkEnabled()) { - CHECK(is_forking_); - GRPC_TRACE_LOG(fork, INFO) << "PostforkChild"; - for (auto it = forkables_.begin(); it != forkables_.end();) { - auto shared = it->lock(); - if (shared) { - shared->PostforkChild(); - ++it; - } else { - it = forkables_.erase(it); - } - } - is_forking_ = false; - } -} - -} // namespace grpc_event_engine::experimental diff --git a/deps/grpc/src/core/lib/event_engine/forkable.h b/deps/grpc/src/core/lib/event_engine/forkable.h deleted file mode 100644 index 73bc77db4ec..00000000000 --- a/deps/grpc/src/core/lib/event_engine/forkable.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2022 gRPC authors. -// -// 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. -#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_FORKABLE_H -#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_FORKABLE_H - -#include - -#include -#include - -#include "src/core/lib/debug/trace.h" - -namespace grpc_event_engine::experimental { - -// An interface to be implemented by EventEngines that wish to have managed fork -// support. The child class must guarantee that those methods are thread-safe. -class Forkable { - public: - virtual ~Forkable() = default; - virtual void PrepareFork() = 0; - virtual void PostforkParent() = 0; - virtual void PostforkChild() = 0; -}; - -// ObjectGroupForkHandler is meant to be used as a static object in each -// translation unit where Forkables are created and registered with the -// ObjectGroupForkHandler. It essentially provides storage for Forkables' -// instances (as a vector of weak pointers) and helper methods that are meant to -// be invoked inside the fork handlers (see pthread_atfork(3)). The idea is to -// have different Forkables (e.g. PosixEventPoller) to store their instances -// (e.g. a PosixEventPoller object) in a single place separated from other -// Forkables (a sharded approach). Forkables need to register their pthread fork -// handlers and manage the relative ordering themselves. This object is -// thread-unsafe. -class ObjectGroupForkHandler { - public: - // Registers a Forkable with this ObjectGroupForkHandler, the Forkable must be - // created as a shared pointer. - void RegisterForkable(std::shared_ptr forkable, - GRPC_UNUSED void (*prepare)(void), - GRPC_UNUSED void (*parent)(void), - GRPC_UNUSED void (*child)(void)); - - void Prefork(); - void PostforkParent(); - void PostforkChild(); - - private: - GRPC_UNUSED bool registered_ = false; - bool is_forking_ = false; - std::vector > forkables_; -}; - -} // namespace grpc_event_engine::experimental - -#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_FORKABLE_H diff --git a/deps/grpc/src/core/lib/event_engine/grpc_polled_fd.h b/deps/grpc/src/core/lib/event_engine/grpc_polled_fd.h index b08280cd4e2..2f02d91bad8 100644 --- a/deps/grpc/src/core/lib/event_engine/grpc_polled_fd.h +++ b/deps/grpc/src/core/lib/event_engine/grpc_polled_fd.h @@ -62,6 +62,9 @@ class GrpcPolledFd { virtual ares_socket_t GetWrappedAresSocketLocked() = 0; // A unique name, for logging virtual const char* GetName() const = 0; + // Return if the FD is "current" - particularly, if it is of the same fork + // generation in case of Posix + virtual bool IsCurrent() const = 0; }; // A GrpcPolledFdFactory is 1-to-1 with and owned by a GrpcAresRequest. It knows @@ -80,6 +83,8 @@ class GrpcPolledFdFactory { ares_socket_t as) = 0; // Optionally configures the ares channel after creation virtual void ConfigureAresChannelLocked(ares_channel channel) = 0; + // Creates a new instance of the same class. This is used during the fork. + virtual std::unique_ptr NewEmptyInstance() const = 0; }; } // namespace grpc_event_engine::experimental diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc index 3c5b8be63af..d8e00dd1ec0 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc @@ -28,6 +28,7 @@ #include "absl/status/statusor.h" #include "absl/strings/str_format.h" #include "src/core/lib/event_engine/poller.h" +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" #include "src/core/lib/event_engine/time_util.h" #include "src/core/lib/iomgr/port.h" #include "src/core/util/crash.h" @@ -46,7 +47,6 @@ #include "src/core/lib/event_engine/posix_engine/posix_engine_closure.h" #include "src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h" #include "src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h" -#include "src/core/util/fork.h" #include "src/core/util/status_helper.h" #include "src/core/util/strerror.h" #include "src/core/util/sync.h" @@ -57,26 +57,24 @@ namespace grpc_event_engine::experimental { class Epoll1EventHandle : public EventHandle { public: - Epoll1EventHandle(int fd, Epoll1Poller* poller) + Epoll1EventHandle(const FileDescriptor& fd, Epoll1Poller* poller) : fd_(fd), - list_(this), poller_(poller), - read_closure_(std::make_unique(poller->GetScheduler())), - write_closure_(std::make_unique(poller->GetScheduler())), - error_closure_( - std::make_unique(poller->GetScheduler())) { - read_closure_->InitEvent(); - write_closure_->InitEvent(); - error_closure_->InitEvent(); + read_closure_(poller->GetScheduler()), + write_closure_(poller->GetScheduler()), + error_closure_(poller->GetScheduler()) { + read_closure_.InitEvent(); + write_closure_.InitEvent(); + error_closure_.InitEvent(); pending_read_.store(false, std::memory_order_relaxed); pending_write_.store(false, std::memory_order_relaxed); pending_error_.store(false, std::memory_order_relaxed); } - void ReInit(int fd) { + void ReInit(FileDescriptor fd) { fd_ = fd; - read_closure_->InitEvent(); - write_closure_->InitEvent(); - error_closure_->InitEvent(); + read_closure_.InitEvent(); + write_closure_.InitEvent(); + error_closure_.InitEvent(); pending_read_.store(false, std::memory_order_relaxed); pending_write_.store(false, std::memory_order_relaxed); pending_error_.store(false, std::memory_order_relaxed); @@ -106,8 +104,8 @@ class Epoll1EventHandle : public EventHandle { return pending_read || pending_write || pending_error; } - int WrappedFd() override { return fd_; } - void OrphanHandle(PosixEngineClosure* on_done, int* release_fd, + FileDescriptor WrappedFd() override { return fd_; } + void OrphanHandle(PosixEngineClosure* on_done, FileDescriptor* release_fd, absl::string_view reason) override; void ShutdownHandle(absl::Status why) override; void NotifyOnRead(PosixEngineClosure* on_read) override; @@ -121,20 +119,19 @@ class Epoll1EventHandle : public EventHandle { // These may execute in Parallel with ShutdownHandle. Thats not an issue // because the lockfree event implementation should be able to handle it. if (pending_read_.exchange(false, std::memory_order_acq_rel)) { - read_closure_->SetReady(); + read_closure_.SetReady(); } if (pending_write_.exchange(false, std::memory_order_acq_rel)) { - write_closure_->SetReady(); + write_closure_.SetReady(); } if (pending_error_.exchange(false, std::memory_order_acq_rel)) { - error_closure_->SetReady(); + error_closure_.SetReady(); } } grpc_core::Mutex* mu() { return &mu_; } - LockfreeEvent* ReadClosure() { return read_closure_.get(); } - LockfreeEvent* WriteClosure() { return write_closure_.get(); } - LockfreeEvent* ErrorClosure() { return error_closure_.get(); } - Epoll1Poller::HandlesList& ForkFdListPos() { return list_; } + LockfreeEvent* ReadClosure() { return &read_closure_; } + LockfreeEvent* WriteClosure() { return &write_closure_; } + LockfreeEvent* ErrorClosure() { return &error_closure_; } ~Epoll1EventHandle() override = default; private: @@ -142,141 +139,80 @@ class Epoll1EventHandle : public EventHandle { // See Epoll1Poller::ShutdownHandle for explanation on why a mutex is // required. grpc_core::Mutex mu_; - int fd_; + FileDescriptor fd_; // See Epoll1Poller::SetPendingActions for explanation on why pending_<***>_ // need to be atomic. std::atomic pending_read_{false}; std::atomic pending_write_{false}; std::atomic pending_error_{false}; - Epoll1Poller::HandlesList list_; Epoll1Poller* poller_; - std::unique_ptr read_closure_; - std::unique_ptr write_closure_; - std::unique_ptr error_closure_; + LockfreeEvent read_closure_; + LockfreeEvent write_closure_; + LockfreeEvent error_closure_; }; namespace { -int EpollCreateAndCloexec() { -#ifdef GRPC_LINUX_EPOLL_CREATE1 - int fd = epoll_create1(EPOLL_CLOEXEC); - if (fd < 0) { - LOG(ERROR) << "epoll_create1 unavailable"; - } -#else - int fd = epoll_create(MAX_EPOLL_EVENTS); - if (fd < 0) { - LOG(ERROR) << "epoll_create unavailable"; - } else if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { - LOG(ERROR) << "fcntl following epoll_create failed"; - return -1; - } -#endif - return fd; -} - -// Only used when GRPC_ENABLE_FORK_SUPPORT=1 -std::list fork_poller_list; - -gpr_mu fork_fd_list_mu; - -void ForkPollerListAddPoller(Epoll1Poller* poller) { - if (grpc_core::Fork::Enabled()) { - gpr_mu_lock(&fork_fd_list_mu); - fork_poller_list.push_back(poller); - gpr_mu_unlock(&fork_fd_list_mu); - } -} - -void ForkPollerListRemovePoller(Epoll1Poller* poller) { - if (grpc_core::Fork::Enabled()) { - gpr_mu_lock(&fork_fd_list_mu); - fork_poller_list.remove(poller); - gpr_mu_unlock(&fork_fd_list_mu); - } -} - -bool InitEpoll1PollerLinux(); - -// Called by the child process's post-fork handler to close open fds, -// including the global epoll fd of each poller. This allows gRPC to shutdown in -// the child process without interfering with connections or RPCs ongoing in the -// parent. -void ResetEventManagerOnFork() { - gpr_mu_lock(&fork_fd_list_mu); - // Delete all registered pollers. This also closes all open epoll_sets - while (!fork_poller_list.empty()) { - Epoll1Poller* poller = fork_poller_list.front(); - fork_poller_list.pop_front(); - poller->Close(); - } - gpr_mu_unlock(&fork_fd_list_mu); - InitEpoll1PollerLinux(); -} - // It is possible that GLIBC has epoll but the underlying kernel doesn't. // Create epoll_fd to make sure epoll support is available bool InitEpoll1PollerLinux() { if (!grpc_event_engine::experimental::SupportsWakeupFd()) { return false; } - int fd = EpollCreateAndCloexec(); - if (fd <= 0) { + EventEnginePosixInterface posix_interface; + auto fd = posix_interface.EpollCreateAndCloexec(); + if (!fd.ok()) { return false; } - if (grpc_core::Fork::Enabled()) { - if (grpc_core::Fork::RegisterResetChildPollingEngineFunc( - ResetEventManagerOnFork)) { - gpr_mu_init(&fork_fd_list_mu); - } - } - close(fd); + posix_interface.Close(fd.value()); return true; } } // namespace void Epoll1EventHandle::OrphanHandle(PosixEngineClosure* on_done, - int* release_fd, + FileDescriptor* release_fd, absl::string_view reason) { bool is_release_fd = (release_fd != nullptr); bool was_shutdown = false; - if (!read_closure_->IsShutdown()) { + if (!read_closure_.IsShutdown()) { was_shutdown = true; HandleShutdownInternal(absl::Status(absl::StatusCode::kUnknown, reason), is_release_fd); } - + auto& posix_interface = poller_->posix_interface(); // If release_fd is not NULL, we should be relinquishing control of the file // descriptor fd->fd (but we still own the grpc_fd structure). if (is_release_fd) { if (!was_shutdown) { - epoll_event phony_event; - if (epoll_ctl(poller_->g_epoll_set_.epfd, EPOLL_CTL_DEL, fd_, - &phony_event) != 0) { - LOG(ERROR) << "OrphanHandle: epoll_ctl failed: " - << grpc_core::StrError(errno); + auto result = + posix_interface.EpollCtlDel(poller_->g_epoll_set_.epfd, fd_); + if (!result.ok()) { + LOG(ERROR) << "OrphanHandle: epoll_ctl failed: " << result.StrError(); } } *release_fd = fd_; } else { - shutdown(fd_, SHUT_RDWR); - close(fd_); + posix_interface.Shutdown(fd_, SHUT_RDWR); + posix_interface.Close(fd_); } { // See Epoll1Poller::ShutdownHandle for explanation on why a mutex is // required here. grpc_core::MutexLock lock(&mu_); - read_closure_->DestroyEvent(); - write_closure_->DestroyEvent(); - error_closure_->DestroyEvent(); + read_closure_.DestroyEvent(); + write_closure_.DestroyEvent(); + error_closure_.DestroyEvent(); } pending_read_.store(false, std::memory_order_release); pending_write_.store(false, std::memory_order_release); pending_error_.store(false, std::memory_order_release); { grpc_core::MutexLock lock(&poller_->mu_); +#ifdef GRPC_ENABLE_FORK_SUPPORT + poller_->fork_handles_set_.erase(this); +#endif // GRPC_ENABLE_FORK_SUPPORT poller_->free_epoll1_handles_list_.push_back(this); } if (on_done != nullptr) { @@ -290,49 +226,45 @@ void Epoll1EventHandle::OrphanHandle(PosixEngineClosure* on_done, // shutdown() syscall on that fd) void Epoll1EventHandle::HandleShutdownInternal(absl::Status why, bool releasing_fd) { - grpc_core::StatusSetInt(&why, grpc_core::StatusIntProperty::kRpcStatus, - GRPC_STATUS_UNAVAILABLE); - if (read_closure_->SetShutdown(why)) { + grpc_core::StatusSetInt( + &why, grpc_core::StatusIntProperty::kRpcStatus, + absl::IsCancelled(why) ? GRPC_STATUS_CANCELLED : GRPC_STATUS_UNAVAILABLE); + if (read_closure_.SetShutdown(why)) { if (releasing_fd) { - epoll_event phony_event; - if (epoll_ctl(poller_->g_epoll_set_.epfd, EPOLL_CTL_DEL, fd_, - &phony_event) != 0) { + auto result = poller_->posix_interface().EpollCtlDel( + poller_->g_epoll_set_.epfd, fd_); + if (!result.ok()) { LOG(ERROR) << "HandleShutdownInternal: epoll_ctl failed: " - << grpc_core::StrError(errno); + << result.StrError(); } } - write_closure_->SetShutdown(why); - error_closure_->SetShutdown(why); + write_closure_.SetShutdown(why); + error_closure_.SetShutdown(why); } } Epoll1Poller::Epoll1Poller(Scheduler* scheduler) : scheduler_(scheduler), was_kicked_(false), closed_(false) { - g_epoll_set_.epfd = EpollCreateAndCloexec(); - wakeup_fd_ = *CreateWakeupFd(); + g_epoll_set_.epfd = posix_interface().EpollCreateAndCloexec().value(); + wakeup_fd_ = CreateWakeupFd(&posix_interface()).value(); CHECK(wakeup_fd_ != nullptr); - CHECK_GE(g_epoll_set_.epfd, 0); + CHECK(g_epoll_set_.epfd.ready()); GRPC_TRACE_LOG(event_engine_poller, INFO) << "grpc epoll fd: " << g_epoll_set_.epfd; - struct epoll_event ev{}; - ev.events = static_cast(EPOLLIN | EPOLLET); - ev.data.ptr = wakeup_fd_.get(); - CHECK(epoll_ctl(g_epoll_set_.epfd, EPOLL_CTL_ADD, wakeup_fd_->ReadFd(), - &ev) == 0); + auto result = posix_interface().EpollCtlAdd( + g_epoll_set_.epfd, false, wakeup_fd_->ReadFd(), wakeup_fd_.get()); + CHECK(result.ok()) << result.StrError(); g_epoll_set_.num_events = 0; g_epoll_set_.cursor = 0; - ForkPollerListAddPoller(this); } -void Epoll1Poller::Shutdown() { ForkPollerListRemovePoller(this); } - void Epoll1Poller::Close() { grpc_core::MutexLock lock(&mu_); if (closed_) return; - if (g_epoll_set_.epfd >= 0) { - close(g_epoll_set_.epfd); - g_epoll_set_.epfd = -1; + if (g_epoll_set_.epfd.ready()) { + posix_interface().Close(g_epoll_set_.epfd); + g_epoll_set_.epfd = FileDescriptor::Invalid(); } while (!free_epoll1_handles_list_.empty()) { @@ -346,7 +278,8 @@ void Epoll1Poller::Close() { Epoll1Poller::~Epoll1Poller() { Close(); } -EventHandle* Epoll1Poller::CreateHandle(int fd, absl::string_view /*name*/, +EventHandle* Epoll1Poller::CreateHandle(FileDescriptor fd, + absl::string_view /*name*/, bool track_err) { Epoll1EventHandle* new_handle = nullptr; { @@ -359,18 +292,21 @@ EventHandle* Epoll1Poller::CreateHandle(int fd, absl::string_view /*name*/, free_epoll1_handles_list_.pop_front(); new_handle->ReInit(fd); } +#ifdef GRPC_ENABLE_FORK_SUPPORT + fork_handles_set_.emplace(new_handle); +#endif // GRPC_ENABLE_FORK_SUPPORT } - struct epoll_event ev; - ev.events = static_cast(EPOLLIN | EPOLLOUT | EPOLLET); // Use the least significant bit of ev.data.ptr to store track_err. We expect // the addresses to be word aligned. We need to store track_err to avoid // synchronization issues when accessing it after receiving an event. // Accessing fd would be a data race there because the fd might have been // returned to the free list at that point. - ev.data.ptr = reinterpret_cast(reinterpret_cast(new_handle) | - (track_err ? 1 : 0)); - if (epoll_ctl(g_epoll_set_.epfd, EPOLL_CTL_ADD, fd, &ev) != 0) { - LOG(ERROR) << "epoll_ctl failed: " << grpc_core::StrError(errno); + auto result = posix_interface().EpollCtlAdd( + g_epoll_set_.epfd, true, fd, + reinterpret_cast(reinterpret_cast(new_handle) | + (track_err ? 1 : 0))); + if (!result.ok()) { + LOG(ERROR) << "epoll_ctl failed: " << result.StrError(); } return new_handle; @@ -421,9 +357,13 @@ bool Epoll1Poller::ProcessEpollEvents(int max_epoll_events_to_handle, // See ProcessEpollEvents() function for more details. It returns the number // of events generated by epoll_wait. int Epoll1Poller::DoEpollWait(EventEngine::Duration timeout) { + auto fd = posix_interface().GetFd(g_epoll_set_.epfd); + if (fd.IsWrongGenerationError()) { + grpc_core::Crash("File descriptor from the wrong generation"); + } int r; do { - r = epoll_wait(g_epoll_set_.epfd, g_epoll_set_.events, MAX_EPOLL_EVENTS, + r = epoll_wait(*fd, g_epoll_set_.events, MAX_EPOLL_EVENTS, static_cast( grpc_event_engine::experimental::Milliseconds(timeout))); } while (r < 0 && errno == EINTR); @@ -450,26 +390,26 @@ void Epoll1EventHandle::ShutdownHandle(absl::Status why) { } bool Epoll1EventHandle::IsHandleShutdown() { - return read_closure_->IsShutdown(); + return read_closure_.IsShutdown(); } void Epoll1EventHandle::NotifyOnRead(PosixEngineClosure* on_read) { - read_closure_->NotifyOn(on_read); + read_closure_.NotifyOn(on_read); } void Epoll1EventHandle::NotifyOnWrite(PosixEngineClosure* on_write) { - write_closure_->NotifyOn(on_write); + write_closure_.NotifyOn(on_write); } void Epoll1EventHandle::NotifyOnError(PosixEngineClosure* on_error) { - error_closure_->NotifyOn(on_error); + error_closure_.NotifyOn(on_error); } -void Epoll1EventHandle::SetReadable() { read_closure_->SetReady(); } +void Epoll1EventHandle::SetReadable() { read_closure_.SetReady(); } -void Epoll1EventHandle::SetWritable() { write_closure_->SetReady(); } +void Epoll1EventHandle::SetWritable() { write_closure_.SetReady(); } -void Epoll1EventHandle::SetHasError() { error_closure_->SetReady(); } +void Epoll1EventHandle::SetHasError() { error_closure_.SetReady(); } // Polls the registered Fds for events until timeout is reached or there is a // Kick(). If there is a Kick(), it collects and processes any previously @@ -516,6 +456,43 @@ void Epoll1Poller::Kick() { CHECK(wakeup_fd_->Wakeup().ok()); } +#ifdef GRPC_ENABLE_FORK_SUPPORT + +void Epoll1Poller::HandleForkInChild() { + // Experiment guards closing fds/incrementing the generation. epoll fd + // needs to be reset outside the experiment to support iomgr + if (grpc_core::IsEventEngineForkEnabled()) { + posix_interface().AdvanceGeneration(); + } + { + grpc_core::MutexLock lock(&mu_); + for (EventHandle* handle : fork_handles_set_) { + handle->ShutdownHandle(absl::CancelledError("Closed on fork")); + } + } + g_epoll_set_ = {}; + g_epoll_set_.epfd = posix_interface().EpollCreateAndCloexec().value(); + CHECK(g_epoll_set_.epfd.ready()); + GRPC_TRACE_LOG(event_engine_poller, INFO) + << "Post-fork grpc epoll fd: " << g_epoll_set_.epfd; + g_epoll_set_.num_events = 0; + g_epoll_set_.cursor = 0; +} + +#endif // GRPC_ENABLE_FORK_SUPPORT + +void Epoll1Poller::ResetKickState() { + // Wakeup fd is always recreated to ensure FD state is reset + // Ok to fail in the fork child + posix_interface().EpollCtlDel(g_epoll_set_.epfd, wakeup_fd_->ReadFd()); + wakeup_fd_ = *CreateWakeupFd(&posix_interface()); + auto status = posix_interface().EpollCtlAdd( + g_epoll_set_.epfd, false, wakeup_fd_->ReadFd(), wakeup_fd_.get()); + CHECK(status.ok()) << status.StrError(); + grpc_core::MutexLock lock(&mu_); + was_kicked_ = false; +} + std::shared_ptr MakeEpoll1Poller(Scheduler* scheduler) { static bool kEpoll1PollerSupported = InitEpoll1PollerLinux(); if (kEpoll1PollerSupported) { @@ -524,14 +501,6 @@ std::shared_ptr MakeEpoll1Poller(Scheduler* scheduler) { return nullptr; } -void Epoll1Poller::PrepareFork() { Kick(); } - -// TODO(vigneshbabu): implement -void Epoll1Poller::PostforkParent() {} - -// TODO(vigneshbabu): implement -void Epoll1Poller::PostforkChild() {} - } // namespace grpc_event_engine::experimental #else // defined(GRPC_LINUX_EPOLL) @@ -546,11 +515,10 @@ Epoll1Poller::Epoll1Poller(Scheduler* /* engine */) { grpc_core::Crash("unimplemented"); } -void Epoll1Poller::Shutdown() { grpc_core::Crash("unimplemented"); } - Epoll1Poller::~Epoll1Poller() { grpc_core::Crash("unimplemented"); } -EventHandle* Epoll1Poller::CreateHandle(int /*fd*/, absl::string_view /*name*/, +EventHandle* Epoll1Poller::CreateHandle(FileDescriptor /*fd*/, + absl::string_view /*name*/, bool /*track_err*/) { grpc_core::Crash("unimplemented"); } @@ -572,18 +540,18 @@ Poller::WorkResult Epoll1Poller::Work( void Epoll1Poller::Kick() { grpc_core::Crash("unimplemented"); } +#if GRPC_ENABLE_FORK_SUPPORT +void Epoll1Poller::HandleForkInChild() { grpc_core::Crash("unimplemented"); } +#endif // GRPC_ENABLE_FORK_SUPPORT + +void Epoll1Poller::ResetKickState() { grpc_core::Crash("unimplemented"); } + // If GRPC_LINUX_EPOLL is not defined, it means epoll is not available. Return // nullptr. std::shared_ptr MakeEpoll1Poller(Scheduler* /*scheduler*/) { return nullptr; } -void Epoll1Poller::PrepareFork() {} - -void Epoll1Poller::PostforkParent() {} - -void Epoll1Poller::PostforkChild() {} - } // namespace grpc_event_engine::experimental #endif // defined(GRPC_POSIX_SOCKET_EV_EPOLL1) diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h index 7ce59f4183d..d3f48eeef5a 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h @@ -22,6 +22,7 @@ #include #include "absl/base/thread_annotations.h" +#include "absl/container/flat_hash_set.h" #include "absl/container/inlined_vector.h" #include "absl/functional/function_ref.h" #include "absl/strings/string_view.h" @@ -46,7 +47,7 @@ class Epoll1EventHandle; class Epoll1Poller : public PosixEventPoller { public: explicit Epoll1Poller(Scheduler* scheduler); - EventHandle* CreateHandle(int fd, absl::string_view name, + EventHandle* CreateHandle(FileDescriptor fd, absl::string_view name, bool track_err) override; Poller::WorkResult Work( grpc_event_engine::experimental::EventEngine::Duration timeout, @@ -54,7 +55,6 @@ class Epoll1Poller : public PosixEventPoller { std::string Name() override { return "epoll1"; } void Kick() override; Scheduler* GetScheduler() { return scheduler_; } - void Shutdown() override; bool CanTrackErrors() const override { #ifdef GRPC_POSIX_SOCKET_TCP return KernelSupportsErrqueue(); @@ -64,13 +64,13 @@ class Epoll1Poller : public PosixEventPoller { } ~Epoll1Poller() override; - // Forkable - void PrepareFork() override; - void PostforkParent() override; - void PostforkChild() override; - void Close(); +#ifdef GRPC_ENABLE_FORK_SUPPORT + void HandleForkInChild() override; +#endif // GRPC_ENABLE_FORK_SUPPORT + void ResetKickState() override; + private: // This initial vector size may need to be tuned using Events = absl::InlinedVector; @@ -90,17 +90,10 @@ class Epoll1Poller : public PosixEventPoller { // of events generated by epoll_wait. int DoEpollWait( grpc_event_engine::experimental::EventEngine::Duration timeout); - class HandlesList { - public: - explicit HandlesList(Epoll1EventHandle* handle) : handle(handle) {} - Epoll1EventHandle* handle; - Epoll1EventHandle* next = nullptr; - Epoll1EventHandle* prev = nullptr; - }; friend class Epoll1EventHandle; #ifdef GRPC_LINUX_EPOLL struct EpollSet { - int epfd = -1; + FileDescriptor epfd; // The epoll_events after the last call to epoll_wait() struct epoll_event events[MAX_EPOLL_EVENTS]{}; @@ -121,6 +114,9 @@ class Epoll1Poller : public PosixEventPoller { EpollSet g_epoll_set_; bool was_kicked_ ABSL_GUARDED_BY(mu_); std::list free_epoll1_handles_list_ ABSL_GUARDED_BY(mu_); +#if GRPC_ENABLE_FORK_SUPPORT + absl::flat_hash_set fork_handles_set_ ABSL_GUARDED_BY(mu_); +#endif // GRPC_ENABLE_FORK_SUPPORT std::unique_ptr wakeup_fd_; bool closed_; }; diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc index 6d7d54c62ee..a54b418fd53 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc @@ -22,8 +22,8 @@ #include #include -#include #include +#include #include #include "absl/container/inlined_vector.h" @@ -35,6 +35,7 @@ #include "src/core/lib/event_engine/poller.h" #include "src/core/lib/event_engine/posix_engine/event_poller.h" #include "src/core/lib/event_engine/posix_engine/posix_engine_closure.h" +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" #include "src/core/lib/iomgr/port.h" #include "src/core/util/crash.h" @@ -51,7 +52,6 @@ #include "src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h" #include "src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h" #include "src/core/lib/event_engine/time_util.h" -#include "src/core/util/fork.h" #include "src/core/util/status_helper.h" #include "src/core/util/strerror.h" #include "src/core/util/sync.h" @@ -68,10 +68,9 @@ using Events = absl::InlinedVector; class PollEventHandle : public EventHandle { public: - PollEventHandle(int fd, std::shared_ptr poller) + PollEventHandle(FileDescriptor fd, std::shared_ptr poller) : fd_(fd), pending_actions_(0), - fork_fd_list_(this), poller_handles_list_(this), scheduler_(poller->GetScheduler()), poller_(std::move(poller)), @@ -108,14 +107,14 @@ class PollEventHandle : public EventHandle { grpc_core::MutexLock lock(&poller_->mu_); poller_->PollerHandlesListRemoveHandle(this); } - int WrappedFd() override { return fd_; } + FileDescriptor WrappedFd() override { return fd_; } bool IsOrphaned() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { return is_orphaned_; } void CloseFd() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { if (!released_ && !closed_) { closed_ = true; - close(fd_); + poller_->posix_interface().Close(fd_); } } bool IsPollhup() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { return pollhup_; } @@ -132,7 +131,7 @@ class PollEventHandle : public EventHandle { void SetWatched(int watch_mask) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { watch_mask_ = watch_mask; } - void OrphanHandle(PosixEngineClosure* on_done, int* release_fd, + void OrphanHandle(PosixEngineClosure* on_done, FileDescriptor* release_fd, absl::string_view reason) override; void ShutdownHandle(absl::Status why) override; void NotifyOnRead(PosixEngineClosure* on_read) override; @@ -183,7 +182,6 @@ class PollEventHandle : public EventHandle { } ~PollEventHandle() override = default; grpc_core::Mutex* mu() ABSL_LOCK_RETURNED(mu_) { return &mu_; } - PollPoller::HandlesList& ForkFdListPos() { return fork_fd_list_; } PollPoller::HandlesList& PollerHandlesListPos() { return poller_handles_list_; } @@ -199,9 +197,8 @@ class PollEventHandle : public EventHandle { // required. grpc_core::Mutex mu_; std::atomic ref_count_{1}; - int fd_; + FileDescriptor fd_; int pending_actions_; - PollPoller::HandlesList fork_fd_list_; PollPoller::HandlesList poller_handles_list_; Scheduler* scheduler_; std::shared_ptr poller_; @@ -219,26 +216,6 @@ class PollEventHandle : public EventHandle { }; namespace { -// Only used when GRPC_ENABLE_FORK_SUPPORT=1 -std::list fork_poller_list; - -gpr_mu fork_fd_list_mu; - -void ForkPollerListAddPoller(PollPoller* poller) { - if (grpc_core::Fork::Enabled()) { - gpr_mu_lock(&fork_fd_list_mu); - fork_poller_list.push_back(poller); - gpr_mu_unlock(&fork_fd_list_mu); - } -} - -void ForkPollerListRemovePoller(PollPoller* poller) { - if (grpc_core::Fork::Enabled()) { - gpr_mu_lock(&fork_fd_list_mu); - fork_poller_list.remove(poller); - gpr_mu_unlock(&fork_fd_list_mu); - } -} // Returns the number of milliseconds elapsed between now and start timestamp. int PollElapsedTimeToMillis(grpc_core::Timestamp start) { @@ -255,42 +232,10 @@ int PollElapsedTimeToMillis(grpc_core::Timestamp start) { } } -bool InitPollPollerPosix(); - -// Called by the child process's post-fork handler to close open fds, -// including the global epoll fd of each poller. This allows gRPC to shutdown -// in the child process without interfering with connections or RPCs ongoing -// in the parent. -void ResetEventManagerOnFork() { - gpr_mu_lock(&fork_fd_list_mu); - // Delete all registered pollers. - while (!fork_poller_list.empty()) { - PollPoller* poller = fork_poller_list.front(); - fork_poller_list.pop_front(); - poller->Close(); - } - gpr_mu_unlock(&fork_fd_list_mu); - InitPollPollerPosix(); -} - -// It is possible that GLIBC has epoll but the underlying kernel doesn't. -// Create epoll_fd to make sure epoll support is available -bool InitPollPollerPosix() { - if (!grpc_event_engine::experimental::SupportsWakeupFd()) { - return false; - } - if (grpc_core::Fork::Enabled()) { - if (grpc_core::Fork::RegisterResetChildPollingEngineFunc( - ResetEventManagerOnFork)) { - gpr_mu_init(&fork_fd_list_mu); - } - } - return true; -} - } // namespace -EventHandle* PollPoller::CreateHandle(int fd, absl::string_view /*name*/, +EventHandle* PollPoller::CreateHandle(FileDescriptor fd, + absl::string_view /*name*/, bool track_err) { // Avoid unused-parameter warning for debug-only parameter (void)track_err; @@ -302,7 +247,8 @@ EventHandle* PollPoller::CreateHandle(int fd, absl::string_view /*name*/, return handle; } -void PollEventHandle::OrphanHandle(PosixEngineClosure* on_done, int* release_fd, +void PollEventHandle::OrphanHandle(PosixEngineClosure* on_done, + FileDescriptor* release_fd, absl::string_view /*reason*/) { ForceRemoveHandleFromPoller(); { @@ -327,7 +273,7 @@ void PollEventHandle::OrphanHandle(PosixEngineClosure* on_done, int* release_fd, } // signal read/write closed to OS so that future operations fail. if (!released_) { - shutdown(fd_, SHUT_RDWR); + poller_->posix_interface().Shutdown(fd_, SHUT_RDWR); } if (!IsWatched()) { CloseFd(); @@ -395,10 +341,11 @@ void PollEventHandle::ShutdownHandle(absl::Status why) { // only shutdown once if (!is_shutdown_) { is_shutdown_ = true; - shutdown_error_ = why; - grpc_core::StatusSetInt(&shutdown_error_, - grpc_core::StatusIntProperty::kRpcStatus, - GRPC_STATUS_UNAVAILABLE); + shutdown_error_ = std::move(why); + grpc_core::StatusSetInt( + &shutdown_error_, grpc_core::StatusIntProperty::kRpcStatus, + absl::IsCancelled(shutdown_error_) ? GRPC_STATUS_CANCELLED + : GRPC_STATUS_UNAVAILABLE); SetReadyLocked(&read_closure_); SetReadyLocked(&write_closure_); } @@ -556,19 +503,6 @@ void PollPoller::PollerHandlesListRemoveHandle(PollEventHandle* handle) { --num_poll_handles_; } -PollPoller::PollPoller(Scheduler* scheduler) - : scheduler_(scheduler), - use_phony_poll_(false), - was_kicked_(false), - was_kicked_ext_(false), - num_poll_handles_(0), - poll_handles_list_head_(nullptr), - closed_(false) { - wakeup_fd_ = *CreateWakeupFd(); - CHECK(wakeup_fd_ != nullptr); - ForkPollerListAddPoller(this); -} - PollPoller::PollPoller(Scheduler* scheduler, bool use_phony_poll) : scheduler_(scheduler), use_phony_poll_(use_phony_poll), @@ -577,9 +511,8 @@ PollPoller::PollPoller(Scheduler* scheduler, bool use_phony_poll) num_poll_handles_(0), poll_handles_list_head_(nullptr), closed_(false) { - wakeup_fd_ = *CreateWakeupFd(); + wakeup_fd_ = *CreateWakeupFd(&posix_interface()); CHECK(wakeup_fd_ != nullptr); - ForkPollerListAddPoller(this); } PollPoller::~PollPoller() { @@ -628,9 +561,12 @@ Poller::WorkResult PollPoller::Work( } pfd_count = 1; - pfds[0].fd = wakeup_fd_->ReadFd(); + auto wakeup_fd = posix_interface().GetFd(wakeup_fd_->ReadFd()); + CHECK(wakeup_fd.ok()) << wakeup_fd.StrError(); + pfds[0].fd = *wakeup_fd; pfds[0].events = POLLIN; pfds[0].revents = 0; + // Event handles from before fork, need to be notified PollEventHandle* head = poll_handles_list_head_; while (head != nullptr) { { @@ -640,27 +576,32 @@ Poller::WorkResult PollPoller::Work( // poll handle list for the poller under the poller lock. CHECK(!head->IsOrphaned()); if (!head->IsPollhup()) { - pfds[pfd_count].fd = head->WrappedFd(); - watchers[pfd_count] = head; - // BeginPollLocked takes a ref of the handle. It also marks the - // fd as Watched with an appropriate watch_mask. The watch_mask - // is 0 if the fd is shutdown or if the fd is already ready (i.e - // both read and write events are already available) and doesn't - // need to be polled again. The watch_mask is > 0 otherwise - // indicating the fd needs to be polled. - pfds[pfd_count].events = head->BeginPollLocked(POLLIN, POLLOUT); - pfd_count++; + if (auto file_descriptor = posix_interface().GetFd(head->WrappedFd()); + file_descriptor.ok()) { + pfds[pfd_count].fd = *file_descriptor; + watchers[pfd_count] = head; + // BeginPollLocked takes a ref of the handle. It also marks the + // fd as Watched with an appropriate watch_mask. The watch_mask + // is 0 if the fd is shutdown or if the fd is already ready (i.e + // both read and write events are already available) and doesn't + // need to be polled again. The watch_mask is > 0 otherwise + // indicating the fd needs to be polled. + pfds[pfd_count].events = head->BeginPollLocked(POLLIN, POLLOUT); + pfd_count++; + } else { + LOG(ERROR) << "Polling FD from a wrong generation: " + << head->WrappedFd(); + } } } head = head->PollerHandlesListPos().next; } mu_.Unlock(); - if (!use_phony_poll_ || timeout_ms == 0 || pfd_count == 1) { // If use_phony_poll is true and pfd_count == 1, it implies only the // wakeup_fd is present. Allow the call to get blocked in this case as // well instead of crashing. This is because the poller::Work is called - // right after an event enging is constructed. Even if phony poll is + // right after an event engine is constructed. Even if phony poll is // expected to be used, we dont want to check for it until some actual // event handles are registered. Otherwise the EventEngine construction // may crash. @@ -778,22 +719,43 @@ Poller::WorkResult PollPoller::Work( return was_kicked_ext ? Poller::WorkResult::kKicked : Poller::WorkResult::kOk; } -void PollPoller::Shutdown() { ForkPollerListRemovePoller(this); } - -void PollPoller::PrepareFork() { Kick(); } -// TODO(vigneshbabu): implement -void PollPoller::PostforkParent() {} -// TODO(vigneshbabu): implement -void PollPoller::PostforkChild() {} - void PollPoller::Close() { grpc_core::MutexLock lock(&mu_); closed_ = true; } +#ifdef GRPC_ENABLE_FORK_SUPPORT +void PollPoller::HandleForkInChild() { + if (grpc_core::IsEventEngineForkEnabled()) { + posix_interface().AdvanceGeneration(); + } + PollEventHandle* handle; + { + grpc_core::MutexLock lock(&mu_); + handle = poll_handles_list_head_; + } + while (handle != nullptr) { + handle->ShutdownHandle(absl::CancelledError("Closed on fork")); + handle = handle->PollerHandlesListPos().next; + } +} +#endif // GRPC_ENABLE_FORK_SUPPORT + +void PollPoller::ResetKickState() { + wakeup_fd_ = *CreateWakeupFd(&posix_interface()); + // Sometimes there's "kick" signalled on the wakeup FD. We need to redo it on + // new fd + // TODO (eostroukhov): Need to consider merging kicked/kicked_ext + // with the wakeup_fd so there's no duplicate state. + grpc_core::MutexLock lock(&mu_); + was_kicked_ = false; + was_kicked_ext_ = false; +} + std::shared_ptr MakePollPoller(Scheduler* scheduler, bool use_phony_poll) { - static bool kPollPollerSupported = InitPollPollerPosix(); + static bool kPollPollerSupported = + grpc_event_engine::experimental::SupportsWakeupFd(); if (kPollPollerSupported) { return std::make_shared(scheduler, use_phony_poll); } @@ -808,15 +770,10 @@ std::shared_ptr MakePollPoller(Scheduler* scheduler, namespace grpc_event_engine::experimental { -PollPoller::PollPoller(Scheduler* /* engine */) { - grpc_core::Crash("unimplemented"); -} - -void PollPoller::Shutdown() { grpc_core::Crash("unimplemented"); } - PollPoller::~PollPoller() { grpc_core::Crash("unimplemented"); } -EventHandle* PollPoller::CreateHandle(int /*fd*/, absl::string_view /*name*/, +EventHandle* PollPoller::CreateHandle(FileDescriptor /*fd*/, + absl::string_view /*name*/, bool /*track_err*/) { grpc_core::Crash("unimplemented"); } @@ -836,10 +793,11 @@ std::shared_ptr MakePollPoller(Scheduler* /*scheduler*/, return nullptr; } -void PollPoller::PrepareFork() { grpc_core::Crash("unimplemented"); } -void PollPoller::PostforkParent() { grpc_core::Crash("unimplemented"); } -void PollPoller::PostforkChild() { grpc_core::Crash("unimplemented"); } +#ifdef GRPC_ENABLE_FORK_SUPPORT +void PollPoller::HandleForkInChild() { grpc_core::Crash("unimplemented"); } +#endif // GRPC_ENABLE_FORK_SUPPORT +void PollPoller::ResetKickState() { grpc_core::Crash("unimplemented"); } void PollPoller::Close() { grpc_core::Crash("unimplemented"); } void PollPoller::KickExternal(bool /*ext*/) { diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.h b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.h index b083d818936..166e18c3bda 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/ev_poll_posix.h @@ -37,9 +37,8 @@ class PollEventHandle; class PollPoller : public PosixEventPoller, public std::enable_shared_from_this { public: - explicit PollPoller(Scheduler* scheduler); - PollPoller(Scheduler* scheduler, bool use_phony_poll); - EventHandle* CreateHandle(int fd, absl::string_view name, + explicit PollPoller(Scheduler* scheduler, bool use_phony_poll = false); + EventHandle* CreateHandle(FileDescriptor fd, absl::string_view name, bool track_err) override; Poller::WorkResult Work( grpc_event_engine::experimental::EventEngine::Duration timeout, @@ -47,17 +46,16 @@ class PollPoller : public PosixEventPoller, std::string Name() override { return "poll"; } void Kick() override; Scheduler* GetScheduler() { return scheduler_; } - void Shutdown() override; bool CanTrackErrors() const override { return false; } ~PollPoller() override; - // Forkable - void PrepareFork() override; - void PostforkParent() override; - void PostforkChild() override; - void Close(); +#ifdef GRPC_ENABLE_FORK_SUPPORT + void HandleForkInChild() override; +#endif // GRPC_ENABLE_FORK_SUPPORT + void ResetKickState() override; + private: void KickExternal(bool ext); void PollerHandlesListAddHandle(PollEventHandle* handle) diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller.h b/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller.h index 51184d3e59a..43eeecef2ad 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller.h +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller.h @@ -22,9 +22,9 @@ #include "absl/functional/any_invocable.h" #include "absl/status/status.h" #include "absl/strings/string_view.h" -#include "src/core/lib/event_engine/forkable.h" #include "src/core/lib/event_engine/poller.h" #include "src/core/lib/event_engine/posix_engine/posix_engine_closure.h" +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" namespace grpc_event_engine::experimental { @@ -39,14 +39,15 @@ class PosixEventPoller; class EventHandle { public: - virtual int WrappedFd() = 0; + virtual FileDescriptor WrappedFd() = 0; // Delete the handle and optionally close the underlying file descriptor if // release_fd != nullptr. The on_done closure is scheduled to be invoked // after the operation is complete. After this operation, NotifyXXX and SetXXX // operations cannot be performed on the handle. In general, this method // should only be called after ShutdownHandle and after all existing NotifyXXX // closures have run and there is no waiting NotifyXXX closure. - virtual void OrphanHandle(PosixEngineClosure* on_done, int* release_fd, + virtual void OrphanHandle(PosixEngineClosure* on_done, + FileDescriptor* release_fd, absl::string_view reason) = 0; // Shutdown a handle. If there is an attempt to call NotifyXXX operations // after Shutdown handle, those closures will be run immediately with the @@ -84,24 +85,26 @@ class EventHandle { virtual ~EventHandle() = default; }; -class PosixEventPoller : public grpc_event_engine::experimental::Poller, - public Forkable { +class PosixEventPoller : public grpc_event_engine::experimental::Poller { public: // Return an opaque handle to perform actions on the provided file descriptor. - virtual EventHandle* CreateHandle(int fd, absl::string_view name, + virtual EventHandle* CreateHandle(FileDescriptor fd, absl::string_view name, bool track_err) = 0; virtual bool CanTrackErrors() const = 0; virtual std::string Name() = 0; - // Shuts down and deletes the poller. It is legal to call this function - // only when no other poller method is in progress. For instance, it is - // not safe to call this method, while a thread is blocked on Work(...). - // A graceful way to terminate the poller could be to: - // 1. First orphan all created handles. - // 2. Send a Kick() to the thread executing Work(...) and wait for the - // thread to return. - // 3. Call Shutdown() on the poller. - virtual void Shutdown() = 0; +#ifdef GRPC_ENABLE_FORK_SUPPORT + // Handles fork in the child process. It performs cleanups like closing file + // descriptors, resetting lingering state to make sure the child and parent + // processes do not interfere with each other and that the child process + // remains in valid state. + virtual void HandleForkInChild() = 0; +#endif // GRPC_ENABLE_FORK_SUPPORT + virtual void ResetKickState() = 0; + EventEnginePosixInterface& posix_interface() { return posix_interface_; } ~PosixEventPoller() override = default; + + private: + EventEnginePosixInterface posix_interface_; }; } // namespace grpc_event_engine::experimental diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc b/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc index c344e09c201..78f4e5edd1d 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc @@ -15,33 +15,19 @@ #include #include -#include #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "src/core/config/config_vars.h" -#include "src/core/lib/event_engine/forkable.h" #include "src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h" #include "src/core/lib/event_engine/posix_engine/ev_poll_posix.h" #include "src/core/lib/event_engine/posix_engine/event_poller.h" #include "src/core/lib/iomgr/port.h" -#include "src/core/util/no_destruct.h" namespace grpc_event_engine::experimental { #ifdef GRPC_POSIX_SOCKET_TCP namespace { -// TODO(yijiem): this object is thread-unsafe, if we are creating pollers in -// multiple threads (e.g. multiple event engines) or if we are creating pollers -// while we are forking then we will run into issues. -grpc_core::NoDestruct g_poller_fork_manager; - -class PollerForkCallbackMethods { - public: - static void Prefork() { g_poller_fork_manager->Prefork(); } - static void PostforkParent() { g_poller_fork_manager->PostforkParent(); } - static void PostforkChild() { g_poller_fork_manager->PostforkChild(); } -}; bool PollStrategyMatches(absl::string_view strategy, absl::string_view want) { return strategy == "all" || strategy == want; @@ -66,10 +52,6 @@ std::shared_ptr MakeDefaultPoller(Scheduler* scheduler) { poller = MakePollPoller(scheduler, /*use_phony_poll=*/true); } } - g_poller_fork_manager->RegisterForkable( - poller, PollerForkCallbackMethods::Prefork, - PollerForkCallbackMethods::PostforkParent, - PollerForkCallbackMethods::PostforkChild); return poller; } diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc b/deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc new file mode 100644 index 00000000000..a6ffbeeb5ac --- /dev/null +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc @@ -0,0 +1,124 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#include "src/core/lib/event_engine/posix_engine/file_descriptor_collection.h" + +#include "absl/strings/substitute.h" +#include "src/core/lib/experiments/experiments.h" +#include "src/core/util/crash.h" // IWYU pragma: keep +#include "src/core/util/strerror.h" + +namespace grpc_event_engine::experimental { + +#ifdef GRPC_ENABLE_FORK_SUPPORT + +namespace { + +bool IsForkEnabled() { return grpc_core::IsEventEngineForkEnabled(); } + +} // namespace + +FileDescriptorCollection::FileDescriptorCollection(int generation) noexcept + : generation_(generation) {} + +FileDescriptorCollection::FileDescriptorCollection( + FileDescriptorCollection&& other) noexcept + : generation_(other.generation_) { + grpc_core::MutexLock lock(&other.mu_); + file_descriptors_ = std::move(other.file_descriptors_); + other.generation_ = -1; + other.file_descriptors_.clear(); +} + +FileDescriptorCollection& FileDescriptorCollection::operator=( + FileDescriptorCollection&& other) noexcept { + generation_ = other.generation_; + grpc_core::MutexLock self_lock(&mu_); + grpc_core::MutexLock other_lock(&other.mu_); + file_descriptors_ = std::move(other.file_descriptors_); + other.generation_ = -1; + other.file_descriptors_.clear(); + return *this; +} + +FileDescriptor FileDescriptorCollection::Add(int fd) { + if (IsForkEnabled()) { + grpc_core::MutexLock lock(&mu_); + file_descriptors_.emplace(fd); + } + return FileDescriptor(fd, generation_); +} + +bool FileDescriptorCollection::Remove(const FileDescriptor& fd) { + if (!IsForkEnabled()) { + return true; + } + if (fd.generation() == generation_) { + grpc_core::MutexLock lock(&mu_); + return file_descriptors_.erase(fd.fd()) == 1; + } + return false; +} + +absl::flat_hash_set +FileDescriptorCollection::ClearAndReturnRawDescriptors() { + if (!IsForkEnabled()) { + return {}; + } + grpc_core::MutexLock lock(&mu_); + absl::flat_hash_set file_descriptors = std::move(file_descriptors_); + // Should not be necessary, but standard is not clear if move would empty + // the collection + file_descriptors_.clear(); + return file_descriptors; +} + +#else // GRPC_ENABLE_FORK_SUPPORT + +FileDescriptorCollection::FileDescriptorCollection( + int /* generation */) noexcept {} + +FileDescriptorCollection::FileDescriptorCollection( + FileDescriptorCollection&& other) noexcept = default; + +FileDescriptorCollection& FileDescriptorCollection::operator=( + FileDescriptorCollection&& other) noexcept = default; + +FileDescriptor FileDescriptorCollection::Add(int fd) { + return FileDescriptor(fd, 0); +} + +bool FileDescriptorCollection::Remove(const FileDescriptor& /* fd */) { + return true; +} + +absl::flat_hash_set +FileDescriptorCollection::ClearAndReturnRawDescriptors() { + return {}; +} + +#endif // GRPC_ENABLE_FORK_SUPPORT + +std::string PosixError::StrError() const { + if (ok()) { + return "ok"; + } + if (IsWrongGenerationError()) { + return "file descriptor was created pre fork"; + } + int value = *errno_value(); + return absl::Substitute("$0 ($1)", grpc_core::StrError(value), value); +} + +} // namespace grpc_event_engine::experimental \ No newline at end of file diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h b/deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h new file mode 100644 index 00000000000..36de68e5fc1 --- /dev/null +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h @@ -0,0 +1,243 @@ +// Copyright 2025 The gRPC Authors +// +// 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. + +#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_FILE_DESCRIPTOR_COLLECTION_H +#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_FILE_DESCRIPTOR_COLLECTION_H + +#include +#include +#include +#include +#include + +#include "absl/container/flat_hash_set.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "src/core/util/sync.h" + +namespace grpc_event_engine::experimental { + +class PosixError { + public: + static constexpr PosixError Ok() { return PosixError(kOk); } + + static constexpr PosixError Error(int errno_value) { + CHECK_GT(errno_value, 0); + return PosixError(errno_value); + } + + static constexpr PosixError WrongGeneration() { + return PosixError(kWrongGenerationError); + } + + constexpr PosixError() : payload_(kOk) {} + + constexpr bool ok() const { return payload_ == kOk; } + + bool IsPosixError() const { return payload_ > 0; } + + bool IsPosixError(int errno_value) const { + return errno_value >= 0 && payload_ == errno_value; + } + + bool IsWrongGenerationError() const { + return payload_ == kWrongGenerationError; + } + + std::optional errno_value() const { + if (payload_ > 0) return payload_; + return std::nullopt; + } + + std::string StrError() const; + + private: + static constexpr int kWrongGenerationError = -1; + static constexpr int kOk = 0; + + explicit constexpr PosixError(int error) : payload_(error) {} + + int payload_; +}; + +template +class PosixErrorOr { + public: + using Payload = std::variant; + + constexpr PosixErrorOr() = default; + constexpr PosixErrorOr(const PosixErrorOr& other) = default; + constexpr PosixErrorOr(PosixErrorOr&& other) = default; + constexpr PosixErrorOr( // NOLINT(google-explicit-constructor) + const PosixError& error) + : value_(error) { + CHECK(!error.ok()); + } + constexpr PosixErrorOr(T&& value) // NOLINT(google-explicit-constructor) + : value_(std::forward(value)) {} + PosixErrorOr& operator=(const PosixErrorOr& other) = default; + PosixErrorOr& operator=(PosixErrorOr&& other) = default; + + bool ok() const { return std::holds_alternative(value_); } + + std::optional errno_value() const { + if (ok()) { + return std::nullopt; + } + return std::get(value_).errno_value(); + } + + bool IsPosixError() const { + const PosixError* error = std::get_if(&value_); + return error != nullptr && error->IsPosixError(); + } + + bool IsPosixError(int errno_value) const { + const PosixError* error = std::get_if(&value_); + return error != nullptr && error->IsPosixError(errno_value); + } + + bool IsWrongGenerationError() const { + const PosixError* error = std::get_if(&value_); + return error != nullptr && error->IsWrongGenerationError(); + } + + T* operator->() { return &std::get(value_); } + + const T* operator->() const { return &std::get(value_); } + + T& operator*() { return std::get(value_); } + + const T& value() const { return std::get(value_); } + + T value_or(T default_value) const { + if (ok()) { + return value(); + } + return default_value; + } + + std::string StrError() const { + if (ok()) { + return "ok"; + } + return std::get(value_).StrError(); + } + + template + friend void AbslStringify(Sink& sink, PosixErrorOr error) { + if (error.ok()) { + sink.Append(absl::StrCat(error.value())); + } else { + sink.Append(error.StrError()); + } + } + + private: + Payload value_; +}; + +// Represents a file descriptor, potentially associated with a fork generation. +// When compiling with fork support (GRPC_ENABLE_FORK_SUPPORT is defined), +// FileDescriptor includes a generation number to track its validity across +// forks. Otherwise, it only stores the fd. +class FileDescriptor { + public: + constexpr FileDescriptor() noexcept = default; +#if GRPC_ENABLE_FORK_SUPPORT + constexpr FileDescriptor(int fd, int generation) noexcept + : fd_(fd), generation_(generation) {}; +#else // GRPC_ENABLE_FORK_SUPPORT + constexpr FileDescriptor(int fd, int /* generation */) noexcept : fd_(fd) {}; +#endif // GRPC_ENABLE_FORK_SUPPORT + + bool ready() const { return fd_ >= 0; } + int fd() const { return fd_; } + constexpr static FileDescriptor Invalid() { return FileDescriptor(-1, 0); } + +#if GRPC_ENABLE_FORK_SUPPORT + int generation() const { return generation_; } + template + friend void AbslStringify(Sink& sink, FileDescriptor fd) { + sink.Append( + absl::StrFormat("fd(%d, generation: %d)", fd.fd_, fd.generation_)); + } + + bool operator==(const FileDescriptor& other) const { + return fd_ == other.fd_ && generation_ == other.generation_; + } +#else // GRPC_ENABLE_FORK_SUPPORT + int generation() const { return 0; } + template + friend void AbslStringify(Sink& sink, FileDescriptor fd) { + sink.Append(absl::StrFormat("fd(%d)", fd.fd_)); + } + bool operator==(const FileDescriptor& other) const { + return fd_ == other.fd_; + } + +#endif // GRPC_ENABLE_FORK_SUPPORT + + friend std::ostream& operator<<(std::ostream& os, const FileDescriptor& fd) { + os << absl::StrCat(fd); + return os; + } + + private: + int fd_ = -1; +#if GRPC_ENABLE_FORK_SUPPORT + int generation_ = 0; +#endif // GRPC_ENABLE_FORK_SUPPORT +}; + +// Manages a collection of file descriptors, tracking their validity across +// forks by associating them with a generation number. This is necessary +// to ensure FDs created before a fork are not used after the fork. +class FileDescriptorCollection { + public: + explicit FileDescriptorCollection(int generation) noexcept; + FileDescriptorCollection(FileDescriptorCollection&& other) noexcept; + FileDescriptorCollection& operator=( + FileDescriptorCollection&& other) noexcept; + // Adds a raw file descriptor `fd` to the collection and associates it + // with the current generation. Simply constructs a new FileDescriptor + // instance without adding to a collection if fork is disabled. + FileDescriptor Add(int fd); + // Removes a FileDescriptor from the collection. + // If fork support is disabled, this always returns true. + // If fork support is enabled, fd is only removed if its generation matches + // the current collection generation. Returns true if the fd was removed. + bool Remove(const FileDescriptor& fd); + // Clears the internal collection and returns a set of file descriptors + absl::flat_hash_set ClearAndReturnRawDescriptors(); + + // Returns the current generation number of the collection. +#if GRPC_ENABLE_FORK_SUPPORT + int generation() const { return generation_; } +#else // GRPC_ENABLE_FORK_SUPPORT + int generation() const { return 0; } +#endif // GRPC_ENABLE_FORK_SUPPORT + + private: +#if GRPC_ENABLE_FORK_SUPPORT + grpc_core::Mutex mu_; + absl::flat_hash_set file_descriptors_ ABSL_GUARDED_BY(mu_); + // Never changed outside of ctor, no need to synchronize + int generation_; +#endif // GRPC_ENABLE_FORK_SUPPORT +}; + +} // namespace grpc_event_engine::experimental + +#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_FILE_DESCRIPTOR_COLLECTION_H diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h b/deps/grpc/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h index 0e38c0487b9..6e312e90731 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h @@ -20,6 +20,9 @@ #include +#include "absl/base/thread_annotations.h" +#include "src/core/lib/event_engine/posix_engine/file_descriptor_collection.h" +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" #include "src/core/lib/iomgr/port.h" #include "src/core/util/sync.h" @@ -31,7 +34,6 @@ #include #include #include -#include #include #include @@ -43,7 +45,6 @@ #include "src/core/lib/event_engine/grpc_polled_fd.h" #include "src/core/lib/event_engine/posix_engine/event_poller.h" #include "src/core/lib/event_engine/posix_engine/posix_engine_closure.h" -#include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h" namespace grpc_event_engine::experimental { @@ -57,7 +58,7 @@ class GrpcPolledFdPosix : public GrpcPolledFd { ~GrpcPolledFdPosix() override { // c-ares library will close the fd. This fd may be picked up immediately by // another thread and should not be closed by the following OrphanHandle. - int phony_release_fd; + FileDescriptor phony_release_fd; handle_->OrphanHandle(/*on_done=*/nullptr, &phony_release_fd, "c-ares query finished"); } @@ -76,8 +77,7 @@ class GrpcPolledFdPosix : public GrpcPolledFd { bool IsFdStillReadableLocked() override { size_t bytes_available = 0; - return ioctl(handle_->WrappedFd(), FIONREAD, &bytes_available) == 0 && - bytes_available > 0; + return ioctl(as_, FIONREAD, &bytes_available) == 0 && bytes_available > 0; } bool ShutdownLocked(absl::Status error) override { @@ -89,6 +89,11 @@ class GrpcPolledFdPosix : public GrpcPolledFd { const char* GetName() const override { return name_.c_str(); } + bool IsCurrent() const override { + return handle_->Poller()->posix_interface().generation() == + handle_->WrappedFd().generation(); + } + private: const std::string name_; const ares_socket_t as_; @@ -101,6 +106,7 @@ class GrpcPolledFdFactoryPosix : public GrpcPolledFdFactory { : poller_(poller) {} ~GrpcPolledFdFactoryPosix() override { + grpc_core::MutexLock lock(&mu_); for (auto& fd : owned_fds_) { close(fd); } @@ -110,16 +116,22 @@ class GrpcPolledFdFactoryPosix : public GrpcPolledFdFactory { std::unique_ptr NewGrpcPolledFdLocked( ares_socket_t as) override { + grpc_core::MutexLock lock(&mu_); owned_fds_.insert(as); + FileDescriptor fd(as, poller_->posix_interface().generation()); return std::make_unique( as, - poller_->CreateHandle(as, "c-ares socket", poller_->CanTrackErrors())); + poller_->CreateHandle(fd, "c-ares socket", poller_->CanTrackErrors())); } void ConfigureAresChannelLocked(ares_channel channel) override { ares_set_socket_functions(channel, &kSockFuncs, this); ares_set_socket_configure_callback( - channel, &GrpcPolledFdFactoryPosix::ConfigureSocket, nullptr); + channel, &GrpcPolledFdFactoryPosix::ConfigureSocket, this); + } + + std::unique_ptr NewEmptyInstance() const override { + return std::make_unique(poller_); } private: @@ -152,6 +164,7 @@ class GrpcPolledFdFactoryPosix : public GrpcPolledFdFactory { static int Close(ares_socket_t as, void* user_data) { GrpcPolledFdFactoryPosix* self = static_cast(user_data); + grpc_core::MutexLock lock(&self->mu_); if (self->owned_fds_.find(as) == self->owned_fds_.end()) { // c-ares owns this fd, grpc has never seen it return close(as); @@ -167,17 +180,13 @@ class GrpcPolledFdFactoryPosix : public GrpcPolledFdFactory { /// - non-blocking /// - cloexec flag /// - disable nagle - static int ConfigureSocket(ares_socket_t fd, int type, void* /*user_data*/) { - // clang-format off -#define RETURN_IF_ERROR(expr) if (!(expr).ok()) { return -1; } - // clang-format on - PosixSocketWrapper sock(fd); - RETURN_IF_ERROR(sock.SetSocketNonBlocking(1)); - RETURN_IF_ERROR(sock.SetSocketCloexec(1)); - if (type == SOCK_STREAM) { - RETURN_IF_ERROR(sock.SetSocketLowLatency(1)); - } - return 0; + static int ConfigureSocket(ares_socket_t as, int type, + void* polled_fd_factory) { + auto& posix_interface = + static_cast(polled_fd_factory) + ->poller_->posix_interface(); + return posix_interface.ConfigureSocket({as, posix_interface.generation()}, + type); } const struct ares_socket_functions kSockFuncs = { @@ -189,9 +198,10 @@ class GrpcPolledFdFactoryPosix : public GrpcPolledFdFactory { }; PosixEventPoller* poller_; + grpc_core::Mutex mu_; // fds that are used/owned by grpc - we (grpc) will close them rather than // c-ares - std::unordered_set owned_fds_; + std::unordered_set owned_fds_ ABSL_GUARDED_BY(mu_); }; } // namespace grpc_event_engine::experimental diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.cc b/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.cc index c5fa3db25b9..18e7909da10 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.cc @@ -17,6 +17,7 @@ #include #include "absl/log/log.h" +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" #include "src/core/lib/iomgr/port.h" #ifdef GRPC_POSIX_SOCKET_TCP @@ -34,10 +35,13 @@ namespace grpc_event_engine::experimental { #ifdef GRPC_LINUX_ERRQUEUE -int GetSocketTcpInfo(struct tcp_info* info, int fd) { +PosixError GetSocketTcpInfo(tcp_info* info, + EventEnginePosixInterface* posix_interface, + const FileDescriptor& fd) { memset(info, 0, sizeof(*info)); info->length = offsetof(tcp_info, length); - return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &(info->length)); + return posix_interface->GetSockOpt(fd, IPPROTO_TCP, TCP_INFO, info, + &(info->length)); } #endif diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.h b/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.h index 5aa4d4a882f..3922afe1d0c 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.h +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/internal_errqueue.h @@ -18,6 +18,7 @@ #include #include +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" #include "src/core/lib/iomgr/port.h" #ifdef GRPC_POSIX_SOCKET_TCP @@ -92,6 +93,8 @@ enum TCPOptStats { TCP_NLA_DSACK_DUPS, // DSACK blocks received TCP_NLA_REORD_SEEN, // reordering events seen TCP_NLA_SRTT, // smoothed RTT in usecs + TCP_NLA_TIMEOUT_REHASH, // Timeout-triggered rehash attempts + TCP_NLA_BYTES_NOTSENT, // Bytes in write queue not yet sent }; // tcp_info from from linux/tcp.h @@ -161,7 +164,9 @@ struct tcp_info { #define TCP_INFO 11 #endif -int GetSocketTcpInfo(tcp_info* info, int fd); +PosixError GetSocketTcpInfo(tcp_info* info, + EventEnginePosixInterface* posix_interface, + const FileDescriptor& fd); #endif // GRPC_LINUX_ERRQUEUE diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.cc b/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.cc index da5230abbf7..528cf77b729 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.cc @@ -29,7 +29,6 @@ #include #include #include -#include #include "absl/functional/any_invocable.h" #include "absl/log/check.h" @@ -40,8 +39,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/event_engine/posix_engine/event_poller.h" #include "src/core/lib/event_engine/posix_engine/internal_errqueue.h" -#include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h" -#include "src/core/lib/event_engine/tcp_socket_utils.h" +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" #include "src/core/lib/experiments/experiments.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/resource_quota/resource_quota.h" @@ -53,7 +51,6 @@ #include "src/core/util/status_helper.h" #include "src/core/util/strerror.h" #include "src/core/util/sync.h" -#include "src/core/util/time.h" #ifdef GRPC_POSIX_SOCKET_TCP #ifdef GRPC_LINUX_ERRQUEUE @@ -98,15 +95,19 @@ namespace { // A wrapper around sendmsg. It sends \a msg over \a fd and returns the number // of bytes sent. -ssize_t TcpSend(int fd, const struct msghdr* msg, int* saved_errno, - int additional_flags = 0) { +PosixErrorOr TcpSend(EventEnginePosixInterface* posix_interface, + const FileDescriptor& fd, + const struct msghdr* msg, int* saved_errno, + int additional_flags = 0) { GRPC_LATENT_SEE_PARENT_SCOPE("TcpSend"); - ssize_t sent_length; + PosixErrorOr send_result; do { grpc_core::global_stats().IncrementSyscallWrite(); - sent_length = sendmsg(fd, msg, SENDMSG_FLAGS | additional_flags); - } while (sent_length < 0 && (*saved_errno = errno) == EINTR); - return sent_length; + send_result = + posix_interface->SendMsg(fd, msg, SENDMSG_FLAGS | additional_flags); + *saved_errno = send_result.errno_value().value_or(0); + } while (send_result.IsPosixError(EINTR)); + return send_result; } #ifdef GRPC_LINUX_ERRQUEUE @@ -211,9 +212,14 @@ bool CmsgIsZeroCopy(const cmsghdr& cmsg) { } #endif // GRPC_LINUX_ERRQUEUE -absl::Status PosixOSError(int error_no, absl::string_view call_name) { - return absl::UnknownError(absl::StrCat( - call_name, ": ", grpc_core::StrError(error_no), " (", error_no, ")")); +absl::Status PosixOSError(const PosixErrorOr& error_no, + absl::string_view call_name) { + if (error_no.IsPosixError()) { + return absl::UnknownError( + absl::StrCat(call_name, ": ", error_no.StrError())); + } + return absl::UnknownError( + absl::StrCat(call_name, ": Wrong file descriptor generation")); } } // namespace @@ -288,7 +294,6 @@ bool PosixEndpointImpl::TcpDoRead(absl::Status& status) { struct msghdr msg; struct iovec iov[MAX_READ_IOVEC]; - ssize_t read_bytes; size_t total_read_bytes = 0; size_t iov_len = std::min(MAX_READ_IOVEC, incoming_buffer_->Count()); #ifdef GRPC_LINUX_ERRQUEUE @@ -330,12 +335,14 @@ bool PosixEndpointImpl::TcpDoRead(absl::Status& status) { grpc_core::global_stats().IncrementTcpReadOffer(incoming_buffer_->Length()); grpc_core::global_stats().IncrementTcpReadOfferIovSize( incoming_buffer_->Count()); + PosixErrorOr res; + EventEnginePosixInterface& posix_interface = poller_->posix_interface(); do { grpc_core::global_stats().IncrementSyscallRead(); - read_bytes = recvmsg(fd_, &msg, 0); - } while (read_bytes < 0 && errno == EINTR); + res = posix_interface.RecvMsg(handle_->WrappedFd(), &msg, 0); + } while (res.IsPosixError(EINTR)); - if (read_bytes < 0 && errno == EAGAIN) { + if (res.IsPosixError(EAGAIN)) { // NB: After calling call_read_cb a parallel call of the read handler may // be running. if (total_read_bytes > 0) { @@ -345,7 +352,7 @@ bool PosixEndpointImpl::TcpDoRead(absl::Status& status) { inq_ = 0; return false; } - + ssize_t read_bytes = res.value_or(-1); // We have read something in previous reads. We need to deliver those bytes // to the upper layer. if (read_bytes <= 0 && total_read_bytes >= 1) { @@ -355,7 +362,12 @@ bool PosixEndpointImpl::TcpDoRead(absl::Status& status) { if (read_bytes <= 0) { // 0 read size ==> end of stream incoming_buffer_->Clear(); - if (read_bytes == 0) { + if (res.IsWrongGenerationError()) { + status = absl::CancelledError("Closed on fork"); + grpc_core::StatusSetInt(&status, + grpc_core::StatusIntProperty::kRpcStatus, + GRPC_STATUS_CANCELLED); + } else if (read_bytes == 0) { status = TcpAnnotateError(absl::InternalError("Socket closed")); } else { status = TcpAnnotateError(absl::InternalError( @@ -363,7 +375,6 @@ bool PosixEndpointImpl::TcpDoRead(absl::Status& status) { } return true; } - grpc_core::global_stats().IncrementTcpReadSize(read_bytes); AddToEstimate(static_cast(read_bytes)); DCHECK((size_t)read_bytes <= incoming_buffer_->Length() - total_read_bytes); @@ -508,11 +519,16 @@ void PosixEndpointImpl::UpdateRcvLowat() { if (set_rcvlowat_ == remaining) { return; } - auto result = sock_.SetSocketRcvLowat(remaining); + // Instruct the kernel to wait for specified number of bytes to be received on + // the socket before generating an interrupt for packet receive. If the call + // succeeds, it returns the number of bytes (wait threshold) that was actually + // set. + auto result = poller_->posix_interface().SetSockOpt( + handle_->WrappedFd(), SOL_SOCKET, SO_RCVLOWAT, remaining); if (result.ok()) { set_rcvlowat_ = *result; } else { - LOG(ERROR) << "ERROR in SO_RCVLOWAT: " << result.status().message(); + LOG(ERROR) << "ERROR in SO_RCVLOWAT: " << result.StrError(); } } @@ -705,17 +721,17 @@ bool PosixEndpointImpl::ProcessErrors() { struct cmsghdr align; } aligned_buf; msg.msg_control = aligned_buf.rbuf; - int r, saved_errno; + PosixErrorOr r; + EventEnginePosixInterface& posix_interface = poller_->posix_interface(); while (true) { msg.msg_controllen = sizeof(aligned_buf.rbuf); do { - r = recvmsg(fd_, &msg, MSG_ERRQUEUE); - saved_errno = errno; - } while (r < 0 && saved_errno == EINTR); + r = posix_interface.RecvMsg(handle_->WrappedFd(), &msg, MSG_ERRQUEUE); + } while (r.IsPosixError(EINTR)); - if (r < 0 && saved_errno == EAGAIN) { + if (r.IsPosixError(EAGAIN)) { return processed_err; // No more errors to process - } else if (r < 0) { + } else if (!r.ok()) { return processed_err; } if (GPR_UNLIKELY((msg.msg_flags & MSG_CTRUNC) != 0)) { @@ -842,13 +858,15 @@ void PosixEndpointImpl::HandleError(absl::Status status) { bool PosixEndpointImpl::WriteWithTimestamps(struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, + PosixErrorOr* sent_length, int* saved_errno, int additional_flags) { + auto& posix_interface = poller_->posix_interface(); if (!socket_ts_enabled_) { - uint32_t opt = kTimestampingSocketOptions; - if (setsockopt(fd_, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), - sizeof(opt)) != 0) { + if (!posix_interface + .SetSockOpt(handle_->WrappedFd(), SOL_SOCKET, SO_TIMESTAMPING, + kTimestampingSocketOptions) + .ok()) { return false; } bytes_counter_ = -1; @@ -867,16 +885,23 @@ bool PosixEndpointImpl::WriteWithTimestamps(struct msghdr* msg, msg->msg_control = u.cmsg_buf; msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t)); + // Add traced buffer before we write to avoid race conditions with getting the + // timestamps from the error queue. If sending fails, we simply shutdown the + // traced buffer list. + traced_buffers_.AddNewEntry( + static_cast(bytes_counter_ + sending_length), + &poller_->posix_interface(), handle_->WrappedFd(), + std::move(outgoing_buffer_write_event_sink_).value()); + outgoing_buffer_write_event_sink_.reset(); + // If there was an error on sendmsg the logic in tcp_flush will handle it. grpc_core::global_stats().IncrementTcpWriteSize(sending_length); - ssize_t length = TcpSend(fd_, msg, saved_errno, additional_flags); - *sent_length = length; - // Only save timestamps if all the bytes were taken by sendmsg. - if (sending_length == static_cast(length)) { - traced_buffers_.AddNewEntry(static_cast(bytes_counter_ + length), - fd_, outgoing_buffer_arg_); - outgoing_buffer_arg_ = nullptr; + PosixErrorOr length = TcpSend(&posix_interface, handle_->WrappedFd(), + msg, saved_errno, additional_flags); + if (!length.ok()) { + return false; } + *sent_length = length; return true; } @@ -892,11 +917,10 @@ void PosixEndpointImpl::HandleError(absl::Status /*status*/) { void PosixEndpointImpl::ZerocopyDisableAndWaitForRemaining() {} -bool PosixEndpointImpl::WriteWithTimestamps(struct msghdr* /*msg*/, - size_t /*sending_length*/, - ssize_t* /*sent_length*/, - int* /*saved_errno*/, - int /*additional_flags*/) { +bool PosixEndpointImpl::WriteWithTimestamps( + struct msghdr* /*msg*/, size_t /*sending_length*/, + PosixErrorOr* /*sent_length*/, int* /*saved_errno*/, + int /*additional_flags*/) { grpc_core::Crash("Write with timestamps not supported for this platform"); } #endif // GRPC_LINUX_ERRQUEUE @@ -909,12 +933,12 @@ void PosixEndpointImpl::UnrefMaybePutZerocopySendRecord( } // If outgoing_buffer_arg is filled, shuts down the list early, so that any -// release operations needed can be performed on the arg. +// release operations needed can be performed on the arg. Should be used when we +// know that there are not gonna be any write timestamps returned on the error +// queue, for example, if the socket is not capable of reporting timestamps. void PosixEndpointImpl::TcpShutdownTracedBufferList() { - if (outgoing_buffer_arg_ != nullptr) { - traced_buffers_.Shutdown(outgoing_buffer_arg_, - absl::InternalError("TracedBuffer list shutdown")); - outgoing_buffer_arg_ = nullptr; + if (outgoing_buffer_write_event_sink_.has_value()) { + traced_buffers_.Shutdown(std::move(outgoing_buffer_write_event_sink_)); } } @@ -922,7 +946,6 @@ void PosixEndpointImpl::TcpShutdownTracedBufferList() { bool PosixEndpointImpl::DoFlushZerocopy(TcpZerocopySendRecord* record, absl::Status& status) { msg_iovlen_type iov_size; - ssize_t sent_length = 0; size_t sending_length; size_t unwind_slice_idx; size_t unwind_byte_idx; @@ -936,6 +959,7 @@ bool PosixEndpointImpl::DoFlushZerocopy(TcpZerocopySendRecord* record, // being populated in most cases. iovec iov[MAX_WRITE_IOVEC]; while (true) { + PosixErrorOr send_status; sending_length = 0; iov_size = record->PopulateIovs(&unwind_slice_idx, &unwind_byte_idx, &sending_length, iov); @@ -950,9 +974,9 @@ bool PosixEndpointImpl::DoFlushZerocopy(TcpZerocopySendRecord* record, // take a single ref on the zerocopy send record. tcp_zerocopy_send_ctx_->NoteSend(record); saved_errno = 0; - if (outgoing_buffer_arg_ != nullptr) { + if (outgoing_buffer_write_event_sink_.has_value()) { if (!ts_capable_ || - !WriteWithTimestamps(&msg, sending_length, &sent_length, &saved_errno, + !WriteWithTimestamps(&msg, sending_length, &send_status, &saved_errno, MSG_ZEROCOPY)) { // We could not set socket options to collect Fathom timestamps. // Fallback on writing without timestamps. @@ -967,7 +991,8 @@ bool PosixEndpointImpl::DoFlushZerocopy(TcpZerocopySendRecord* record, msg.msg_controllen = 0; grpc_core::global_stats().IncrementTcpWriteSize(sending_length); grpc_core::global_stats().IncrementTcpWriteIovSize(iov_size); - sent_length = TcpSend(fd_, &msg, &saved_errno, MSG_ZEROCOPY); + send_status = TcpSend(&poller_->posix_interface(), handle_->WrappedFd(), + &msg, &saved_errno, MSG_ZEROCOPY); } if (tcp_zerocopy_send_ctx_->UpdateZeroCopyOptMemStateAfterSend( saved_errno == ENOBUFS, constrained) || @@ -997,21 +1022,21 @@ bool PosixEndpointImpl::DoFlushZerocopy(TcpZerocopySendRecord* record, #endif } } - if (sent_length < 0) { + if (!send_status.ok()) { // If this particular send failed, drop ref taken earlier in this method. tcp_zerocopy_send_ctx_->UndoSend(); - if (saved_errno == EAGAIN || saved_errno == ENOBUFS) { + if (send_status.IsPosixError(EAGAIN) || + send_status.IsPosixError(ENOBUFS)) { record->UnwindIfThrottled(unwind_slice_idx, unwind_byte_idx); return false; } else { - status = TcpAnnotateError(PosixOSError(saved_errno, "sendmsg")); - TcpShutdownTracedBufferList(); + status = TcpAnnotateError(PosixOSError(send_status, "sendmsg")); return true; } } - bytes_counter_ += sent_length; + bytes_counter_ += *send_status; record->UpdateOffsetForBytesSent(sending_length, - static_cast(sent_length)); + static_cast(*send_status)); if (record->AllSlicesSent()) { return true; } @@ -1033,7 +1058,6 @@ bool PosixEndpointImpl::TcpFlush(absl::Status& status) { struct msghdr msg; struct iovec iov[MAX_WRITE_IOVEC]; msg_iovlen_type iov_size; - ssize_t sent_length = 0; size_t sending_length; size_t trailing; size_t unwind_slice_idx; @@ -1046,6 +1070,7 @@ bool PosixEndpointImpl::TcpFlush(absl::Status& status) { size_t outgoing_slice_idx = 0; while (true) { + PosixErrorOr send_result; sending_length = 0; unwind_slice_idx = outgoing_slice_idx; unwind_byte_idx = outgoing_byte_idx_; @@ -1070,9 +1095,9 @@ bool PosixEndpointImpl::TcpFlush(absl::Status& status) { msg.msg_flags = 0; bool tried_sending_message = false; saved_errno = 0; - if (outgoing_buffer_arg_ != nullptr) { + if (outgoing_buffer_write_event_sink_.has_value()) { if (!ts_capable_ || !WriteWithTimestamps(&msg, sending_length, - &sent_length, &saved_errno, 0)) { + &send_result, &saved_errno, 0)) { // We could not set socket options to collect Fathom timestamps. // Fallback on writing without timestamps. ts_capable_ = false; @@ -1086,11 +1111,13 @@ bool PosixEndpointImpl::TcpFlush(absl::Status& status) { msg.msg_controllen = 0; grpc_core::global_stats().IncrementTcpWriteSize(sending_length); grpc_core::global_stats().IncrementTcpWriteIovSize(iov_size); - sent_length = TcpSend(fd_, &msg, &saved_errno); + send_result = TcpSend(&poller_->posix_interface(), handle_->WrappedFd(), + &msg, &saved_errno); } - if (sent_length < 0) { - if (saved_errno == EAGAIN || saved_errno == ENOBUFS) { + if (!send_result.ok()) { + if (send_result.IsPosixError(EAGAIN) || + send_result.IsPosixError(ENOBUFS)) { outgoing_byte_idx_ = unwind_byte_idx; // unref all and forget about all slices that have been written to this // point @@ -1099,16 +1126,15 @@ bool PosixEndpointImpl::TcpFlush(absl::Status& status) { } return false; } else { - status = TcpAnnotateError(PosixOSError(saved_errno, "sendmsg")); + status = TcpAnnotateError(PosixOSError(send_result, "sendmsg")); outgoing_buffer_->Clear(); - TcpShutdownTracedBufferList(); return true; } } CHECK_EQ(outgoing_byte_idx_, 0u); - bytes_counter_ += sent_length; - trailing = sending_length - static_cast(sent_length); + bytes_counter_ += *send_result; + trailing = sending_length - static_cast(*send_result); while (trailing > 0) { size_t slice_length; outgoing_slice_idx--; @@ -1172,7 +1198,8 @@ bool PosixEndpointImpl::Write( << "Endpoint[" << this << "]: Write " << data->Length() << " bytes"; if (data->Length() == 0) { - TcpShutdownTracedBufferList(); + GRPC_TRACE_LOG(event_engine_endpoint, INFO) + << "Endpoint[" << this << "]: Write skipped"; if (handle_->IsHandleShutdown()) { status = TcpAnnotateError(absl::InternalError("EOF")); engine_->Run( @@ -1183,8 +1210,6 @@ bool PosixEndpointImpl::Write( }); return false; } - GRPC_TRACE_LOG(event_engine_endpoint, INFO) - << "Endpoint[" << this << "]: Write skipped"; return true; } @@ -1194,10 +1219,8 @@ bool PosixEndpointImpl::Write( outgoing_buffer_ = data; outgoing_byte_idx_ = 0; } - outgoing_buffer_arg_ = - args.GetDeprecatedAndDiscouragedGoogleSpecificPointer(); - if (outgoing_buffer_arg_) { - CHECK(poller_->CanTrackErrors()); + if (args.has_metrics_sink() && poller_->CanTrackErrors()) { + outgoing_buffer_write_event_sink_ = args.TakeMetricsSink(); } bool flush_result = zerocopy_send_record != nullptr @@ -1247,12 +1270,12 @@ void PosixEndpointImpl::MaybeShutdown( } PosixEndpointImpl ::~PosixEndpointImpl() { - int release_fd = -1; + FileDescriptor release_fd; handle_->OrphanHandle(on_done_, on_release_fd_ == nullptr ? nullptr : &release_fd, ""); if (on_release_fd_ != nullptr) { engine_->Run([on_release_fd = std::move(on_release_fd_), - release_fd]() mutable { on_release_fd(release_fd); }); + release_fd]() mutable { on_release_fd(release_fd.fd()); }); } delete on_read_; delete on_write_; @@ -1264,24 +1287,23 @@ PosixEndpointImpl::PosixEndpointImpl(EventHandle* handle, std::shared_ptr engine, MemoryAllocator&& /*allocator*/, const PosixTcpOptions& options) - : sock_(PosixSocketWrapper(handle->WrappedFd())), - on_done_(on_done), + : on_done_(on_done), traced_buffers_(), handle_(handle), poller_(handle->Poller()), engine_(engine) { - PosixSocketWrapper sock(handle->WrappedFd()); - fd_ = handle_->WrappedFd(); + FileDescriptor fd = handle_->WrappedFd(); CHECK(options.resource_quota != nullptr); - auto peer_addr_string = sock.PeerAddressString(); + auto& posix_interface = poller_->posix_interface(); + auto peer_addr_string = posix_interface.PeerAddressString(fd); mem_quota_ = options.resource_quota->memory_quota(); memory_owner_ = mem_quota_->CreateMemoryOwner(); self_reservation_ = memory_owner_.MakeReservation(sizeof(PosixEndpointImpl)); - auto local_address = sock.LocalAddress(); + auto local_address = posix_interface.LocalAddress(fd); if (local_address.ok()) { local_address_ = *local_address; } - auto peer_address = sock.PeerAddress(); + auto peer_address = posix_interface.PeerAddress(fd); if (peer_address.ok()) { peer_address_ = *peer_address; } @@ -1304,14 +1326,11 @@ PosixEndpointImpl::PosixEndpointImpl(EventHandle* handle, << "ulimit value is not set. Use ulimit -l to set its " << "value."; } else { - const int enable = 1; - if (setsockopt(fd_, SOL_SOCKET, SO_ZEROCOPY, &enable, sizeof(enable)) != - 0) { + if (posix_interface.SetSockOpt(fd, SOL_SOCKET, SO_ZEROCOPY, 1).ok()) { zerocopy_enabled = false; LOG(ERROR) << "Failed to set zerocopy options on the socket."; } } - if (zerocopy_enabled) { VLOG(2) << "Tx-zero copy enabled for gRPC sends. RLIMIT_MEMLOCK value " << "=" << GetRLimitMemLockMax() @@ -1323,11 +1342,11 @@ PosixEndpointImpl::PosixEndpointImpl(EventHandle* handle, zerocopy_enabled, options.tcp_tx_zerocopy_max_simultaneous_sends, options.tcp_tx_zerocopy_send_bytes_threshold); #ifdef GRPC_HAVE_TCP_INQ - int one = 1; - if (setsockopt(fd_, SOL_TCP, TCP_INQ, &one, sizeof(one)) == 0) { + auto result = posix_interface.SetSockOpt(fd, SOL_TCP, TCP_INQ, 1); + if (result.ok()) { inq_capable_ = true; } else { - VLOG(2) << "cannot set inq fd=" << fd_ << " errno=" << errno; + VLOG(2) << "cannot set inq fd=" << fd << " error=" << result.StrError(); inq_capable_ = false; } #else @@ -1348,6 +1367,40 @@ PosixEndpointImpl::PosixEndpointImpl(EventHandle* handle, } } +namespace { +class PosixEndpointTelemetryInfo : public EventEngine::Endpoint::TelemetryInfo { + public: + std::vector AllWriteMetrics() const override { + return PosixWriteEventSink::AllWriteMetrics(); + } + + std::optional GetMetricName(size_t key) const override { + return PosixWriteEventSink::GetMetricName(key); + } + + std::optional GetMetricKey(absl::string_view name) const override { + return PosixWriteEventSink::GetMetricKey(name); + } + + std::shared_ptr GetMetricsSet( + absl::Span keys) const override { + return PosixWriteEventSink::GetMetricsSet(keys); + } + + std::shared_ptr GetFullMetricsSet() + const override { + return PosixWriteEventSink::GetFullMetricsSet(); + } +}; +} // namespace + +std::shared_ptr +PosixEndpoint::GetTelemetryInfo() const { + static absl::NoDestructor> + telemetry_info(std::make_shared()); + return *telemetry_info; +} + std::unique_ptr CreatePosixEndpoint( EventHandle* handle, PosixEngineClosure* on_shutdown, std::shared_ptr engine, MemoryAllocator&& allocator, diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.h b/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.h index e8752e8e850..681800d959b 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.h +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/posix_endpoint.h @@ -27,19 +27,15 @@ #include #include #include -#include -#include #include #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" -#include "absl/hash/hash.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "src/core/lib/event_engine/extensions/supports_fd.h" #include "src/core/lib/event_engine/posix.h" #include "src/core/lib/event_engine/posix_engine/event_poller.h" #include "src/core/lib/event_engine/posix_engine/posix_engine_closure.h" @@ -488,7 +484,7 @@ class PosixEndpointImpl : public grpc_core::RefCounted { return local_address_; } - int GetWrappedFd() { return fd_; } + FileDescriptor GetWrappedFd() { return handle_->WrappedFd(); } bool CanTrackErrors() const { return poller_->CanTrackErrors(); } @@ -519,7 +515,7 @@ class PosixEndpointImpl : public grpc_core::RefCounted { void UnrefMaybePutZerocopySendRecord(TcpZerocopySendRecord* record); void ZerocopyDisableAndWaitForRemaining(); bool WriteWithTimestamps(struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, int* saved_errno, + PosixErrorOr* sent_length, int* saved_errno, int additional_flags); absl::Status TcpAnnotateError(absl::Status src_error) const; #ifdef GRPC_LINUX_ERRQUEUE @@ -530,16 +526,13 @@ class PosixEndpointImpl : public grpc_core::RefCounted { struct cmsghdr* ProcessTimestamp(msghdr* msg, struct cmsghdr* cmsg); #endif // GRPC_LINUX_ERRQUEUE grpc_core::Mutex read_mu_; - PosixSocketWrapper sock_; - int fd_; bool is_first_read_ = true; bool has_posted_reclaimer_ ABSL_GUARDED_BY(read_mu_) = false; double target_length_; int min_read_chunk_size_; int max_read_chunk_size_; - int set_rcvlowat_ = 0; + int64_t set_rcvlowat_ = 0; double bytes_read_this_round_ = 0; - std::atomic ref_count_{1}; // garbage after the last read. grpc_event_engine::experimental::SliceBuffer last_read_buffer_; @@ -571,7 +564,9 @@ class PosixEndpointImpl : public grpc_core::RefCounted { grpc_core::MemoryOwner memory_owner_; grpc_core::MemoryAllocator::Reservation self_reservation_; - void* outgoing_buffer_arg_ = nullptr; + std::optional< + grpc_event_engine::experimental::EventEngine::Endpoint::WriteEventSink> + outgoing_buffer_write_event_sink_; absl::AnyInvocable)> on_release_fd_ = nullptr; @@ -623,13 +618,8 @@ class PosixEndpoint : public PosixEndpointWithFdSupport { return impl_->Write(std::move(on_writable), data, std::move(args)); } - std::vector AllWriteMetrics() override { return {}; } - std::optional GetMetricName(size_t) override { - return std::nullopt; - } - std::optional GetMetricKey(absl::string_view) override { - return std::nullopt; - } + std::shared_ptr GetTelemetryInfo() + const override; const grpc_event_engine::experimental::EventEngine::ResolvedAddress& GetPeerAddress() const override { @@ -640,7 +630,7 @@ class PosixEndpoint : public PosixEndpointWithFdSupport { return impl_->GetLocalAddress(); } - int GetWrappedFd() override { return impl_->GetWrappedFd(); } + int GetWrappedFd() override { return impl_->GetWrappedFd().fd(); } bool CanTrackErrors() override { return impl_->CanTrackErrors(); } diff --git a/deps/grpc/src/core/lib/event_engine/posix_engine/posix_engine.cc b/deps/grpc/src/core/lib/event_engine/posix_engine/posix_engine.cc index d5aa2a27d96..dc23d0b9995 100644 --- a/deps/grpc/src/core/lib/event_engine/posix_engine/posix_engine.cc +++ b/deps/grpc/src/core/lib/event_engine/posix_engine/posix_engine.cc @@ -21,43 +21,46 @@ #include #include -#include #include #include #include #include #include #include +#include +#include "absl/base/no_destructor.h" #include "absl/cleanup/cleanup.h" +#include "absl/container/inlined_vector.h" #include "absl/functional/any_invocable.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "absl/status/status.h" -#include "absl/strings/match.h" #include "absl/strings/str_cat.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/event_engine/ares_resolver.h" -#include "src/core/lib/event_engine/forkable.h" -#include "src/core/lib/event_engine/grpc_polled_fd.h" #include "src/core/lib/event_engine/poller.h" #include "src/core/lib/event_engine/posix.h" #include "src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h" #include "src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h" +#include "src/core/lib/event_engine/posix_engine/posix_interface.h" #include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h" #include "src/core/lib/event_engine/posix_engine/timer.h" +#include "src/core/lib/event_engine/posix_engine/timer_manager.h" #include "src/core/lib/event_engine/tcp_socket_utils.h" #include "src/core/lib/event_engine/utils.h" #include "src/core/lib/experiments/experiments.h" #include "src/core/util/crash.h" -#include "src/core/util/no_destruct.h" +#include "src/core/util/fork.h" #include "src/core/util/sync.h" #include "src/core/util/useful.h" #ifdef GRPC_POSIX_SOCKET_TCP #include // IWYU pragma: keep +#include // IWYU pragma: keep #include // IWYU pragma: keep #include // IWYU pragma: keep +#include // IWYU pragma: keep #include "src/core/lib/event_engine/posix_engine/event_poller.h" #include "src/core/lib/event_engine/posix_engine/event_poller_posix_default.h" @@ -80,19 +83,194 @@ namespace grpc_event_engine::experimental { namespace { -grpc_core::NoDestruct g_timer_fork_manager; - -class TimerForkCallbackMethods { - public: - static void Prefork() { g_timer_fork_manager->Prefork(); } - static void PostforkParent() { g_timer_fork_manager->PostforkParent(); } - static void PostforkChild() { g_timer_fork_manager->PostforkChild(); } +#if GRPC_ENABLE_FORK_SUPPORT && GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK + +// Thread pool can outlive EE but we need to ensure the ordering if both +// entities are alive. +template