| 
					
				 | 
			
			
				@@ -196,8 +196,7 @@ struct grpc_call { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   union { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       grpc_status_code *status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      char **status_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      size_t *status_details_capacity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_slice *status_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       int *cancelled; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -383,7 +382,7 @@ static void get_final_status(grpc_call *call, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                              void *set_value_user_data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (i = 0; i < STATUS_SOURCE_COUNT; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (call->status[i].is_set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (call->status[i].is_code_set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       set_value(call->status[i].code, set_value_user_data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -411,8 +410,8 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_mu_destroy(&c->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (i = 0; i < STATUS_SOURCE_COUNT; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (c->status[i].details) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      GRPC_MDSTR_UNREF(exec_ctx, c->status[i].details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (c->status[i].is_details_set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_slice_unref_internal(exec_ctx, c->status[i].details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (ii = 0; ii < c->send_extra_metadata_count; ii++) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -438,18 +437,19 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void set_status_code(grpc_call *call, status_source source, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             uint32_t status) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (call->status[source].is_set) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (call->status[source].is_code_set) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  call->status[source].is_set = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  call->status[source].is_code_set = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   call->status[source].code = (grpc_status_code)status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void set_status_details(grpc_exec_ctx *exec_ctx, grpc_call *call, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                status_source source, grpc_slice status) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (call->status[source].details != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    GRPC_MDSTR_UNREF(exec_ctx, status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (call->status[source].is_details_set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_slice_unref_internal(exec_ctx, status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     call->status[source].details = status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    call->status[source].is_details_set = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -459,7 +459,8 @@ static void set_status_from_error(grpc_exec_ctx *exec_ctx, grpc_call *call, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const char *msg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_error_get_status(error, &status, &msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   set_status_code(call, source, (uint32_t)status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  set_status_details(exec_ctx, call, source, grpc_mdstr_from_string(msg)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  set_status_details(exec_ctx, call, source, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     grpc_slice_from_copied_string(msg)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void set_incoming_compression_algorithm( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -509,7 +510,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  accept_encoding_slice = mdel->value->slice; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  accept_encoding_slice = mdel->value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_slice_buffer_init(&accept_encoding_parts); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -518,15 +519,13 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* Always support no compression */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (i = 0; i < accept_encoding_parts.count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const grpc_slice *accept_encoding_entry_slice = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        &accept_encoding_parts.slices[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (grpc_compression_algorithm_parse( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (const char *)GRPC_SLICE_START_PTR(*accept_encoding_entry_slice), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            GRPC_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_slice accept_encoding_entry_slice = accept_encoding_parts.slices[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (grpc_compression_algorithm_parse(accept_encoding_entry_slice, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                         &algorithm)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       GPR_BITSET(&call->encodings_accepted_by_peer, algorithm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       char *accept_encoding_entry_str = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          grpc_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          grpc_dump_slice(accept_encoding_entry_slice, GPR_DUMP_ASCII); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_log(GPR_ERROR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               "Invalid entry in accept encoding metadata: '%s'. Ignoring.", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               accept_encoding_entry_str); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -549,21 +548,12 @@ uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return encodings_accepted_by_peer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void get_final_details(grpc_call *call, char **out_details, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                              size_t *out_details_capacity) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void get_final_details(grpc_call *call, grpc_slice *out_details) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (i = 0; i < STATUS_SOURCE_COUNT; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (call->status[i].is_set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (call->status[i].details) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        grpc_slice details = call->status[i].details->slice; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        size_t len = GRPC_SLICE_LENGTH(details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (len + 1 > *out_details_capacity) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          *out_details_capacity = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              GPR_MAX(len + 1, *out_details_capacity * 3 / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          *out_details = gpr_realloc(*out_details, *out_details_capacity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        memcpy(*out_details, GRPC_SLICE_START_PTR(details), len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (*out_details)[len] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (call->status[i].is_code_set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (call->status[i].is_details_set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        *out_details = grpc_slice_ref(call->status[i].details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         goto no_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -572,11 +562,7 @@ static void get_final_details(grpc_call *call, char **out_details, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 no_details: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (0 == *out_details_capacity) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    *out_details_capacity = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    *out_details = gpr_malloc(*out_details_capacity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  **out_details = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  *out_details = grpc_empty_slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -605,19 +591,17 @@ static int prepare_application_metadata( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         get_md_elem(metadata, additional_metadata, i, count); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    l->md = grpc_mdelem_from_string_and_buffer( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        exec_ctx, md->key, (const uint8_t *)md->value, md->value_length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                  GRPC_MDSTR_LENGTH(l->md->key))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              grpc_mdstr_as_c_string(l->md->key)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    l->md = grpc_mdelem_from_slices(exec_ctx, md->key, md->value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!grpc_header_key_slice_is_legal(l->md->key)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      char *str = grpc_dump_slice(md->key, GPR_DUMP_ASCII); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_free(str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                      GRPC_MDSTR_LENGTH(l->md->key)) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               !grpc_header_nonbin_value_is_legal( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                   grpc_mdstr_as_c_string(l->md->value), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                   GRPC_MDSTR_LENGTH(l->md->value))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gpr_log(GPR_ERROR, "attempt to send invalid metadata value"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (!grpc_slice_is_binary_header(l->md->key) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               !grpc_header_nonbin_value_slice_is_legal(l->md->value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      char *str = grpc_dump_slice(md->value, GPR_DUMP_HEX | GPR_DUMP_ASCII); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_log(GPR_ERROR, "attempt to send invalid metadata value: %s", str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_free(str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -902,9 +886,7 @@ static uint32_t decode_status(grpc_mdelem *md) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (user_data != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     status = ((uint32_t)(intptr_t)user_data) - STATUS_OFFSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                   GRPC_SLICE_LENGTH(md->value->slice), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                   &status)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!grpc_parse_slice_to_uint32(md->value, &status)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       status = GRPC_STATUS_UNKNOWN; /* could not parse status code */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_mdelem_set_user_data(md, destroy_status, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -915,13 +897,14 @@ static uint32_t decode_status(grpc_mdelem *md) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static grpc_compression_algorithm decode_compression(grpc_mdelem *md) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_compression_algorithm algorithm = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      grpc_compression_algorithm_from_mdstr(md->value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_compression_algorithm_from_slice(md->value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const char *md_c_str = grpc_mdstr_as_c_string(md->value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char *md_c_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_log(GPR_ERROR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             "Invalid incoming compression algorithm: '%s'. Interpreting " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             "incoming data as uncompressed.", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             md_c_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_free(md_c_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return GRPC_COMPRESS_NONE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return algorithm; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -929,15 +912,15 @@ static grpc_compression_algorithm decode_compression(grpc_mdelem *md) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static grpc_mdelem *recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        grpc_mdelem *elem) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (elem->key == GRPC_MDSTR_GRPC_STATUS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_STATUS) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_BEGIN("status", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     set_status_code(call, STATUS_FROM_WIRE, decode_status(elem)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_END("status", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_BEGIN("status-details", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     set_status_details(exec_ctx, call, STATUS_FROM_WIRE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       GRPC_MDSTR_REF(elem->value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       grpc_slice_ref_internal(elem->value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_END("status-details", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -956,9 +939,8 @@ static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   mdusr = &dest->metadata[dest->count++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  mdusr->key = grpc_mdstr_as_c_string(elem->key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  mdusr->value = grpc_mdstr_as_c_string(elem->value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  mdusr->value_length = GRPC_SLICE_LENGTH(elem->value->slice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mdusr->key = grpc_slice_ref(elem->key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mdusr->value = grpc_slice_ref(elem->value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_TIMER_END("publish_app_metadata", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return elem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -973,12 +955,12 @@ static grpc_mdelem *recv_initial_filter(void *args, grpc_mdelem *elem) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   elem = recv_common_filter(a->exec_ctx, a->call, elem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (elem == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ENCODING) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_BEGIN("incoming_compression_algorithm", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     set_incoming_compression_algorithm(a->call, decode_compression(elem)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_END("incoming_compression_algorithm", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ACCEPT_ENCODING) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     set_encodings_accepted_by_peer(a->exec_ctx, a->call, elem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_TIMER_END("encodings_accepted_by_peer", 0); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1328,8 +1310,7 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (call->is_client) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       get_final_status(call, set_status_value_directly, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        call->final_op.client.status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      get_final_details(call, call->final_op.client.status_details, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        call->final_op.client.status_details_capacity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get_final_details(call, call->final_op.client.status_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       get_final_status(call, set_cancelled_value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        call->final_op.server.cancelled); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1427,13 +1408,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           const grpc_compression_algorithm calgo = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               compression_algorithm_for_level_locked( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                   call, effective_compression_level); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          char *calgo_name = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          grpc_compression_algorithm_name(calgo, &calgo_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           // the following will be picked up by the compress filter and used as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           // the call's compression algorithm. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          compression_md.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          compression_md.value = calgo_name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          compression_md.value_length = strlen(calgo_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          compression_md.value = grpc_compression_algorithm_slice(calgo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           additional_metadata_count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1527,14 +1505,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             exec_ctx, call->channel, op->data.send_status_from_server.status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (op->data.send_status_from_server.status_details != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          call->send_extra_metadata[1].md = grpc_mdelem_from_slices( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              grpc_mdstr_from_string( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  op->data.send_status_from_server.status_details)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              grpc_slice_ref_internal( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  *op->data.send_status_from_server.status_details)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           call->send_extra_metadata_count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           set_status_details( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               exec_ctx, call, STATUS_FROM_API_OVERRIDE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              grpc_slice_ref_internal(call->send_extra_metadata[1].md->value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (op->data.send_status_from_server.status != GRPC_STATUS_OK) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           set_status_code(call, STATUS_FROM_API_OVERRIDE, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1611,8 +1589,6 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         call->final_op.client.status = op->data.recv_status_on_client.status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         call->final_op.client.status_details = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             op->data.recv_status_on_client.status_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        call->final_op.client.status_details_capacity = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            op->data.recv_status_on_client.status_details_capacity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         bctl->recv_final_op = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         stream_op->recv_trailing_metadata = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; 
			 |