|  | @@ -40,7 +40,9 @@
 | 
	
		
			
				|  |  |  #include <grpc/support/time.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include "src/core/lib/slice/slice_hash_table.h"
 | 
	
		
			
				|  |  | +#include "src/core/lib/slice/slice_internal.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/transport/metadata.h"
 | 
	
		
			
				|  |  | +#include "src/core/lib/transport/static_metadata.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //
 | 
	
		
			
				|  |  |  // grpc_method_config
 | 
	
	
		
			
				|  | @@ -48,37 +50,37 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // bool vtable
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void* bool_copy(void* valuep) {
 | 
	
		
			
				|  |  | -  bool value = *(bool*)valuep;
 | 
	
		
			
				|  |  | -  bool* new_value = gpr_malloc(sizeof(bool));
 | 
	
		
			
				|  |  | +static void *bool_copy(void *valuep) {
 | 
	
		
			
				|  |  | +  bool value = *(bool *)valuep;
 | 
	
		
			
				|  |  | +  bool *new_value = gpr_malloc(sizeof(bool));
 | 
	
		
			
				|  |  |    *new_value = value;
 | 
	
		
			
				|  |  |    return new_value;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int bool_cmp(void* v1, void* v2) {
 | 
	
		
			
				|  |  | -  bool b1 = *(bool*)v1;
 | 
	
		
			
				|  |  | -  bool b2 = *(bool*)v2;
 | 
	
		
			
				|  |  | +static int bool_cmp(void *v1, void *v2) {
 | 
	
		
			
				|  |  | +  bool b1 = *(bool *)v1;
 | 
	
		
			
				|  |  | +  bool b2 = *(bool *)v2;
 | 
	
		
			
				|  |  |    if (!b1 && b2) return -1;
 | 
	
		
			
				|  |  |    if (b1 && !b2) return 1;
 | 
	
		
			
				|  |  |    return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void free_mem(grpc_exec_ctx* exec_ctx, void* p) { gpr_free(p); }
 | 
	
		
			
				|  |  | +static void free_mem(grpc_exec_ctx *exec_ctx, void *p) { gpr_free(p); }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static grpc_slice_hash_table_vtable bool_vtable = {free_mem, bool_copy,
 | 
	
		
			
				|  |  |                                                     bool_cmp};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // timespec vtable
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void* timespec_copy(void* valuep) {
 | 
	
		
			
				|  |  | -  gpr_timespec value = *(gpr_timespec*)valuep;
 | 
	
		
			
				|  |  | -  gpr_timespec* new_value = gpr_malloc(sizeof(gpr_timespec));
 | 
	
		
			
				|  |  | +static void *timespec_copy(void *valuep) {
 | 
	
		
			
				|  |  | +  gpr_timespec value = *(gpr_timespec *)valuep;
 | 
	
		
			
				|  |  | +  gpr_timespec *new_value = gpr_malloc(sizeof(gpr_timespec));
 | 
	
		
			
				|  |  |    *new_value = value;
 | 
	
		
			
				|  |  |    return new_value;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int timespec_cmp(void* v1, void* v2) {
 | 
	
		
			
				|  |  | -  return gpr_time_cmp(*(gpr_timespec*)v1, *(gpr_timespec*)v2);
 | 
	
		
			
				|  |  | +static int timespec_cmp(void *v1, void *v2) {
 | 
	
		
			
				|  |  | +  return gpr_time_cmp(*(gpr_timespec *)v1, *(gpr_timespec *)v2);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static grpc_slice_hash_table_vtable timespec_vtable = {free_mem, timespec_copy,
 | 
	
	
		
			
				|  | @@ -86,16 +88,16 @@ static grpc_slice_hash_table_vtable timespec_vtable = {free_mem, timespec_copy,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // int32 vtable
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void* int32_copy(void* valuep) {
 | 
	
		
			
				|  |  | -  int32_t value = *(int32_t*)valuep;
 | 
	
		
			
				|  |  | -  int32_t* new_value = gpr_malloc(sizeof(int32_t));
 | 
	
		
			
				|  |  | +static void *int32_copy(void *valuep) {
 | 
	
		
			
				|  |  | +  int32_t value = *(int32_t *)valuep;
 | 
	
		
			
				|  |  | +  int32_t *new_value = gpr_malloc(sizeof(int32_t));
 | 
	
		
			
				|  |  |    *new_value = value;
 | 
	
		
			
				|  |  |    return new_value;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int int32_cmp(void* v1, void* v2) {
 | 
	
		
			
				|  |  | -  int32_t i1 = *(int32_t*)v1;
 | 
	
		
			
				|  |  | -  int32_t i2 = *(int32_t*)v2;
 | 
	
		
			
				|  |  | +static int int32_cmp(void *v1, void *v2) {
 | 
	
		
			
				|  |  | +  int32_t i1 = *(int32_t *)v1;
 | 
	
		
			
				|  |  | +  int32_t i2 = *(int32_t *)v2;
 | 
	
		
			
				|  |  |    if (i1 < i2) return -1;
 | 
	
		
			
				|  |  |    if (i1 > i2) return 1;
 | 
	
		
			
				|  |  |    return 0;
 | 
	
	
		
			
				|  | @@ -104,57 +106,37 @@ static int int32_cmp(void* v1, void* v2) {
 | 
	
		
			
				|  |  |  static grpc_slice_hash_table_vtable int32_vtable = {free_mem, int32_copy,
 | 
	
		
			
				|  |  |                                                      int32_cmp};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// Hash table keys.
 | 
	
		
			
				|  |  | -#define GRPC_METHOD_CONFIG_WAIT_FOR_READY "grpc.wait_for_ready"  // bool
 | 
	
		
			
				|  |  | -#define GRPC_METHOD_CONFIG_TIMEOUT "grpc.timeout"                // gpr_timespec
 | 
	
		
			
				|  |  | -#define GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES \
 | 
	
		
			
				|  |  | -  "grpc.max_request_message_bytes"  // int32
 | 
	
		
			
				|  |  | -#define GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES \
 | 
	
		
			
				|  |  | -  "grpc.max_response_message_bytes"  // int32
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  struct grpc_method_config {
 | 
	
		
			
				|  |  | -  grpc_slice_hash_table* table;
 | 
	
		
			
				|  |  | -  grpc_slice  wait_for_ready_key;
 | 
	
		
			
				|  |  | -  grpc_slice  timeout_key;
 | 
	
		
			
				|  |  | -  grpc_slice  max_request_message_bytes_key;
 | 
	
		
			
				|  |  | -  grpc_slice  max_response_message_bytes_key;
 | 
	
		
			
				|  |  | +  grpc_slice_hash_table *table;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -grpc_method_config* grpc_method_config_create(
 | 
	
		
			
				|  |  | -    bool* wait_for_ready, gpr_timespec* timeout,
 | 
	
		
			
				|  |  | -    int32_t* max_request_message_bytes, int32_t* max_response_message_bytes) {
 | 
	
		
			
				|  |  | -  grpc_method_config* method_config = gpr_malloc(sizeof(grpc_method_config));
 | 
	
		
			
				|  |  | +grpc_method_config *grpc_method_config_create(
 | 
	
		
			
				|  |  | +    bool *wait_for_ready, gpr_timespec *timeout,
 | 
	
		
			
				|  |  | +    int32_t *max_request_message_bytes, int32_t *max_response_message_bytes) {
 | 
	
		
			
				|  |  | +  grpc_method_config *method_config = gpr_malloc(sizeof(grpc_method_config));
 | 
	
		
			
				|  |  |    memset(method_config, 0, sizeof(grpc_method_config));
 | 
	
		
			
				|  |  | -  method_config->wait_for_ready_key =
 | 
	
		
			
				|  |  | -      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_WAIT_FOR_READY);
 | 
	
		
			
				|  |  | -  method_config->timeout_key =
 | 
	
		
			
				|  |  | -      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_TIMEOUT);
 | 
	
		
			
				|  |  | -  method_config->max_request_message_bytes_key =
 | 
	
		
			
				|  |  | -      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES);
 | 
	
		
			
				|  |  | -  method_config->max_response_message_bytes_key =
 | 
	
		
			
				|  |  | -      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES);
 | 
	
		
			
				|  |  |    grpc_slice_hash_table_entry entries[4];
 | 
	
		
			
				|  |  |    size_t num_entries = 0;
 | 
	
		
			
				|  |  |    if (wait_for_ready != NULL) {
 | 
	
		
			
				|  |  | -    entries[num_entries].key = method_config->wait_for_ready_key;
 | 
	
		
			
				|  |  | +    entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY;
 | 
	
		
			
				|  |  |      entries[num_entries].value = wait_for_ready;
 | 
	
		
			
				|  |  |      entries[num_entries].vtable = &bool_vtable;
 | 
	
		
			
				|  |  |      ++num_entries;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    if (timeout != NULL) {
 | 
	
		
			
				|  |  | -    entries[num_entries].key = method_config->timeout_key;
 | 
	
		
			
				|  |  | +    entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_TIMEOUT;
 | 
	
		
			
				|  |  |      entries[num_entries].value = timeout;
 | 
	
		
			
				|  |  |      entries[num_entries].vtable = ×pec_vtable;
 | 
	
		
			
				|  |  |      ++num_entries;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    if (max_request_message_bytes != NULL) {
 | 
	
		
			
				|  |  | -    entries[num_entries].key = method_config->max_request_message_bytes_key;
 | 
	
		
			
				|  |  | +    entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES;
 | 
	
		
			
				|  |  |      entries[num_entries].value = max_request_message_bytes;
 | 
	
		
			
				|  |  |      entries[num_entries].vtable = &int32_vtable;
 | 
	
		
			
				|  |  |      ++num_entries;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    if (max_response_message_bytes != NULL) {
 | 
	
		
			
				|  |  | -    entries[num_entries].key = method_config->max_response_message_bytes_key;
 | 
	
		
			
				|  |  | +    entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES;
 | 
	
		
			
				|  |  |      entries[num_entries].value = max_response_message_bytes;
 | 
	
		
			
				|  |  |      entries[num_entries].vtable = &int32_vtable;
 | 
	
		
			
				|  |  |      ++num_entries;
 | 
	
	
		
			
				|  | @@ -163,137 +145,129 @@ grpc_method_config* grpc_method_config_create(
 | 
	
		
			
				|  |  |    return method_config;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config) {
 | 
	
		
			
				|  |  | +grpc_method_config *grpc_method_config_ref(grpc_method_config *method_config) {
 | 
	
		
			
				|  |  |    grpc_slice_hash_table_ref(method_config->table);
 | 
	
		
			
				|  |  |    return method_config;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void grpc_method_config_unref(grpc_exec_ctx* exec_ctx,
 | 
	
		
			
				|  |  | -                              grpc_method_config* method_config) {
 | 
	
		
			
				|  |  | +void grpc_method_config_unref(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | +                              grpc_method_config *method_config) {
 | 
	
		
			
				|  |  |    if (grpc_slice_hash_table_unref(exec_ctx, method_config->table)) {
 | 
	
		
			
				|  |  | -    GRPC_MDSTR_UNREF(exec_ctx, method_config->wait_for_ready_key);
 | 
	
		
			
				|  |  | -    GRPC_MDSTR_UNREF(exec_ctx, method_config->timeout_key);
 | 
	
		
			
				|  |  | -    GRPC_MDSTR_UNREF(exec_ctx, method_config->max_request_message_bytes_key);
 | 
	
		
			
				|  |  | -    GRPC_MDSTR_UNREF(exec_ctx, method_config->max_response_message_bytes_key);
 | 
	
		
			
				|  |  |      gpr_free(method_config);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -int grpc_method_config_cmp(const grpc_method_config* method_config1,
 | 
	
		
			
				|  |  | -                           const grpc_method_config* method_config2) {
 | 
	
		
			
				|  |  | +int grpc_method_config_cmp(const grpc_method_config *method_config1,
 | 
	
		
			
				|  |  | +                           const grpc_method_config *method_config2) {
 | 
	
		
			
				|  |  |    return grpc_slice_hash_table_cmp(method_config1->table,
 | 
	
		
			
				|  |  |                                     method_config2->table);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -const bool* grpc_method_config_get_wait_for_ready(
 | 
	
		
			
				|  |  | -    const grpc_method_config* method_config) {
 | 
	
		
			
				|  |  | +const bool *grpc_method_config_get_wait_for_ready(
 | 
	
		
			
				|  |  | +    const grpc_method_config *method_config) {
 | 
	
		
			
				|  |  |    return grpc_slice_hash_table_get(method_config->table,
 | 
	
		
			
				|  |  | -                                   method_config->wait_for_ready_key);
 | 
	
		
			
				|  |  | +                                   GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -const gpr_timespec* grpc_method_config_get_timeout(
 | 
	
		
			
				|  |  | -    const grpc_method_config* method_config) {
 | 
	
		
			
				|  |  | +const gpr_timespec *grpc_method_config_get_timeout(
 | 
	
		
			
				|  |  | +    const grpc_method_config *method_config) {
 | 
	
		
			
				|  |  |    return grpc_slice_hash_table_get(method_config->table,
 | 
	
		
			
				|  |  | -                                   method_config->timeout_key);
 | 
	
		
			
				|  |  | +                                   GRPC_MDSTR_GRPC_DOT_TIMEOUT);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -const int32_t* grpc_method_config_get_max_request_message_bytes(
 | 
	
		
			
				|  |  | -    const grpc_method_config* method_config) {
 | 
	
		
			
				|  |  | +const int32_t *grpc_method_config_get_max_request_message_bytes(
 | 
	
		
			
				|  |  | +    const grpc_method_config *method_config) {
 | 
	
		
			
				|  |  |    return grpc_slice_hash_table_get(
 | 
	
		
			
				|  |  | -      method_config->table, method_config->max_request_message_bytes_key);
 | 
	
		
			
				|  |  | +      method_config->table, GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -const int32_t* grpc_method_config_get_max_response_message_bytes(
 | 
	
		
			
				|  |  | -    const grpc_method_config* method_config) {
 | 
	
		
			
				|  |  | +const int32_t *grpc_method_config_get_max_response_message_bytes(
 | 
	
		
			
				|  |  | +    const grpc_method_config *method_config) {
 | 
	
		
			
				|  |  |    return grpc_slice_hash_table_get(
 | 
	
		
			
				|  |  | -      method_config->table, method_config->max_response_message_bytes_key);
 | 
	
		
			
				|  |  | +      method_config->table, GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //
 | 
	
		
			
				|  |  |  // grpc_method_config_table
 | 
	
		
			
				|  |  |  //
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void method_config_unref(grpc_exec_ctx* exec_ctx, void* valuep) {
 | 
	
		
			
				|  |  | +static void method_config_unref(grpc_exec_ctx *exec_ctx, void *valuep) {
 | 
	
		
			
				|  |  |    grpc_method_config_unref(exec_ctx, valuep);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void* method_config_ref(void* valuep) {
 | 
	
		
			
				|  |  | +static void *method_config_ref(void *valuep) {
 | 
	
		
			
				|  |  |    return grpc_method_config_ref(valuep);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int method_config_cmp(void* valuep1, void* valuep2) {
 | 
	
		
			
				|  |  | +static int method_config_cmp(void *valuep1, void *valuep2) {
 | 
	
		
			
				|  |  |    return grpc_method_config_cmp(valuep1, valuep2);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static const grpc_slice_hash_table_vtable method_config_table_vtable = {
 | 
	
		
			
				|  |  |      method_config_unref, method_config_ref, method_config_cmp};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -grpc_method_config_table* grpc_method_config_table_create(
 | 
	
		
			
				|  |  | -    size_t num_entries, grpc_method_config_table_entry* entries) {
 | 
	
		
			
				|  |  | -  grpc_slice_hash_table_entry* hash_table_entries =
 | 
	
		
			
				|  |  | +grpc_method_config_table *grpc_method_config_table_create(
 | 
	
		
			
				|  |  | +    size_t num_entries, grpc_method_config_table_entry *entries) {
 | 
	
		
			
				|  |  | +  grpc_slice_hash_table_entry *hash_table_entries =
 | 
	
		
			
				|  |  |        gpr_malloc(sizeof(grpc_slice_hash_table_entry) * num_entries);
 | 
	
		
			
				|  |  |    for (size_t i = 0; i < num_entries; ++i) {
 | 
	
		
			
				|  |  |      hash_table_entries[i].key = entries[i].method_name;
 | 
	
		
			
				|  |  |      hash_table_entries[i].value = entries[i].method_config;
 | 
	
		
			
				|  |  |      hash_table_entries[i].vtable = &method_config_table_vtable;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  grpc_method_config_table* method_config_table =
 | 
	
		
			
				|  |  | +  grpc_method_config_table *method_config_table =
 | 
	
		
			
				|  |  |        grpc_slice_hash_table_create(num_entries, hash_table_entries);
 | 
	
		
			
				|  |  |    gpr_free(hash_table_entries);
 | 
	
		
			
				|  |  |    return method_config_table;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -grpc_method_config_table* grpc_method_config_table_ref(
 | 
	
		
			
				|  |  | -    grpc_method_config_table* table) {
 | 
	
		
			
				|  |  | +grpc_method_config_table *grpc_method_config_table_ref(
 | 
	
		
			
				|  |  | +    grpc_method_config_table *table) {
 | 
	
		
			
				|  |  |    return grpc_slice_hash_table_ref(table);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void grpc_method_config_table_unref(grpc_exec_ctx* exec_ctx,
 | 
	
		
			
				|  |  | -                                    grpc_method_config_table* table) {
 | 
	
		
			
				|  |  | +void grpc_method_config_table_unref(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | +                                    grpc_method_config_table *table) {
 | 
	
		
			
				|  |  |    grpc_slice_hash_table_unref(exec_ctx, table);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -int grpc_method_config_table_cmp(const grpc_method_config_table* table1,
 | 
	
		
			
				|  |  | -                                 const grpc_method_config_table* table2) {
 | 
	
		
			
				|  |  | +int grpc_method_config_table_cmp(const grpc_method_config_table *table1,
 | 
	
		
			
				|  |  | +                                 const grpc_method_config_table *table2) {
 | 
	
		
			
				|  |  |    return grpc_slice_hash_table_cmp(table1, table2);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
 | 
	
		
			
				|  |  | -                                   const grpc_slice_hash_table* table,
 | 
	
		
			
				|  |  | -                                   const grpc_slice  path) {
 | 
	
		
			
				|  |  | -  void* value = grpc_slice_hash_table_get(table, path);
 | 
	
		
			
				|  |  | +void *grpc_method_config_table_get(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | +                                   const grpc_slice_hash_table *table,
 | 
	
		
			
				|  |  | +                                   const grpc_slice path) {
 | 
	
		
			
				|  |  | +  void *value = grpc_slice_hash_table_get(table, path);
 | 
	
		
			
				|  |  |    // If we didn't find a match for the path, try looking for a wildcard
 | 
	
		
			
				|  |  |    // entry (i.e., change "/service/method" to "/service/*").
 | 
	
		
			
				|  |  |    if (value == NULL) {
 | 
	
		
			
				|  |  | -    const char* path_str = grpc_mdstr_as_c_string(path);
 | 
	
		
			
				|  |  | -    const char* sep = strrchr(path_str, '/') + 1;
 | 
	
		
			
				|  |  | -    const size_t len = (size_t)(sep - path_str);
 | 
	
		
			
				|  |  | -    char* buf = gpr_malloc(len + 2);  // '*' and NUL
 | 
	
		
			
				|  |  | -    memcpy(buf, path_str, len);
 | 
	
		
			
				|  |  | -    buf[len] = '*';
 | 
	
		
			
				|  |  | -    buf[len + 1] = '\0';
 | 
	
		
			
				|  |  | -    grpc_slice  wildcard_path = grpc_mdstr_from_string(buf);
 | 
	
		
			
				|  |  | -    gpr_free(buf);
 | 
	
		
			
				|  |  | -    value = grpc_slice_hash_table_get(table, wildcard_path);
 | 
	
		
			
				|  |  | -    GRPC_MDSTR_UNREF(exec_ctx, wildcard_path);
 | 
	
		
			
				|  |  | +    int sep_pos = grpc_slice_rchr(path, '/') + 1;
 | 
	
		
			
				|  |  | +    grpc_slice search = grpc_slice_malloc((size_t)(sep_pos + 1));
 | 
	
		
			
				|  |  | +    memcpy(GRPC_SLICE_START_PTR(search), GRPC_SLICE_START_PTR(path),
 | 
	
		
			
				|  |  | +           (size_t)sep_pos);
 | 
	
		
			
				|  |  | +    GRPC_SLICE_START_PTR(search)[sep_pos] = '*';
 | 
	
		
			
				|  |  | +    value = grpc_slice_hash_table_get(table, search);
 | 
	
		
			
				|  |  | +    grpc_slice_unref_internal(exec_ctx, search);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    return value;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void* copy_arg(void* p) { return grpc_method_config_table_ref(p); }
 | 
	
		
			
				|  |  | +static void *copy_arg(void *p) { return grpc_method_config_table_ref(p); }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void destroy_arg(grpc_exec_ctx* exec_ctx, void* p) {
 | 
	
		
			
				|  |  | +static void destroy_arg(grpc_exec_ctx *exec_ctx, void *p) {
 | 
	
		
			
				|  |  |    grpc_method_config_table_unref(exec_ctx, p);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int cmp_arg(void* p1, void* p2) {
 | 
	
		
			
				|  |  | +static int cmp_arg(void *p1, void *p2) {
 | 
	
		
			
				|  |  |    return grpc_method_config_table_cmp(p1, p2);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static grpc_arg_pointer_vtable arg_vtable = {copy_arg, destroy_arg, cmp_arg};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  grpc_arg grpc_method_config_table_create_channel_arg(
 | 
	
		
			
				|  |  | -    grpc_method_config_table* table) {
 | 
	
		
			
				|  |  | +    grpc_method_config_table *table) {
 | 
	
		
			
				|  |  |    grpc_arg arg;
 | 
	
		
			
				|  |  |    arg.type = GRPC_ARG_POINTER;
 | 
	
		
			
				|  |  |    arg.key = GRPC_ARG_SERVICE_CONFIG;
 | 
	
	
		
			
				|  | @@ -304,27 +278,27 @@ grpc_arg grpc_method_config_table_create_channel_arg(
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // State used by convert_entry() below.
 | 
	
		
			
				|  |  |  typedef struct conversion_state {
 | 
	
		
			
				|  |  | -  void* (*convert_value)(const grpc_method_config* method_config);
 | 
	
		
			
				|  |  | -  const grpc_slice_hash_table_vtable* vtable;
 | 
	
		
			
				|  |  | +  void *(*convert_value)(const grpc_method_config *method_config);
 | 
	
		
			
				|  |  | +  const grpc_slice_hash_table_vtable *vtable;
 | 
	
		
			
				|  |  |    size_t num_entries;
 | 
	
		
			
				|  |  | -  grpc_slice_hash_table_entry* entries;
 | 
	
		
			
				|  |  | +  grpc_slice_hash_table_entry *entries;
 | 
	
		
			
				|  |  |  } conversion_state;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // A function to be passed to grpc_slice_hash_table_iterate() to create
 | 
	
		
			
				|  |  |  // a copy of the entries.
 | 
	
		
			
				|  |  | -static void convert_entry(const grpc_slice_hash_table_entry* entry,
 | 
	
		
			
				|  |  | -                          void* user_data) {
 | 
	
		
			
				|  |  | -  conversion_state* state = user_data;
 | 
	
		
			
				|  |  | -  state->entries[state->num_entries].key = GRPC_MDSTR_REF(entry->key);
 | 
	
		
			
				|  |  | +static void convert_entry(const grpc_slice_hash_table_entry *entry,
 | 
	
		
			
				|  |  | +                          void *user_data) {
 | 
	
		
			
				|  |  | +  conversion_state *state = user_data;
 | 
	
		
			
				|  |  | +  state->entries[state->num_entries].key = grpc_slice_ref_internal(entry->key);
 | 
	
		
			
				|  |  |    state->entries[state->num_entries].value = state->convert_value(entry->value);
 | 
	
		
			
				|  |  |    state->entries[state->num_entries].vtable = state->vtable;
 | 
	
		
			
				|  |  |    ++state->num_entries;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -grpc_slice_hash_table* grpc_method_config_table_convert(
 | 
	
		
			
				|  |  | -    grpc_exec_ctx* exec_ctx, const grpc_method_config_table* table,
 | 
	
		
			
				|  |  | -    void* (*convert_value)(const grpc_method_config* method_config),
 | 
	
		
			
				|  |  | -    const grpc_slice_hash_table_vtable* vtable) {
 | 
	
		
			
				|  |  | +grpc_slice_hash_table *grpc_method_config_table_convert(
 | 
	
		
			
				|  |  | +    grpc_exec_ctx *exec_ctx, const grpc_method_config_table *table,
 | 
	
		
			
				|  |  | +    void *(*convert_value)(const grpc_method_config *method_config),
 | 
	
		
			
				|  |  | +    const grpc_slice_hash_table_vtable *vtable) {
 | 
	
		
			
				|  |  |    // Create an array of the entries in the table with converted values.
 | 
	
		
			
				|  |  |    conversion_state state;
 | 
	
		
			
				|  |  |    state.convert_value = convert_value;
 | 
	
	
		
			
				|  | @@ -334,11 +308,11 @@ grpc_slice_hash_table* grpc_method_config_table_convert(
 | 
	
		
			
				|  |  |                               grpc_slice_hash_table_num_entries(table));
 | 
	
		
			
				|  |  |    grpc_slice_hash_table_iterate(table, convert_entry, &state);
 | 
	
		
			
				|  |  |    // Create a new table based on the array we just constructed.
 | 
	
		
			
				|  |  | -  grpc_slice_hash_table* new_table =
 | 
	
		
			
				|  |  | +  grpc_slice_hash_table *new_table =
 | 
	
		
			
				|  |  |        grpc_slice_hash_table_create(state.num_entries, state.entries);
 | 
	
		
			
				|  |  |    // Clean up the array.
 | 
	
		
			
				|  |  |    for (size_t i = 0; i < state.num_entries; ++i) {
 | 
	
		
			
				|  |  | -    GRPC_MDSTR_UNREF(exec_ctx, state.entries[i].key);
 | 
	
		
			
				|  |  | +    grpc_slice_unref_internal(exec_ctx, state.entries[i].key);
 | 
	
		
			
				|  |  |      vtable->destroy_value(exec_ctx, state.entries[i].value);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    gpr_free(state.entries);
 |