aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/transport/metadata.c
diff options
context:
space:
mode:
authorGravatar yang-g <yangg@google.com>2016-03-30 14:58:53 -0700
committerGravatar yang-g <yangg@google.com>2016-03-30 14:58:53 -0700
commitcb7a80266b4fb867481807dc439d3c002f74d466 (patch)
tree33f11445bae0bb5a46e1b34fcd7d8779cd16a002 /src/core/lib/transport/metadata.c
parent503c3caf0804c7b9e2619f7c58de6b2b415a8fb0 (diff)
Use base64 encoded length for decoder table size
Diffstat (limited to 'src/core/lib/transport/metadata.c')
-rw-r--r--src/core/lib/transport/metadata.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index 451c8d1cd3..b1005f317a 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -38,6 +38,7 @@
#include <string.h>
#include <grpc/compression.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
@@ -93,6 +94,9 @@ typedef struct internal_string {
gpr_slice base64_and_huffman;
+ uint8_t has_size_in_decoder_table;
+ size_t size_in_decoder_table;
+
struct internal_string *bucket_next;
} internal_string;
@@ -407,6 +411,8 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
}
s->has_base64_and_huffman_encoded = 0;
s->hash = hash;
+ s->has_size_in_decoder_table = 0;
+ s->size_in_decoder_table = 0;
s->bucket_next = shard->strs[idx];
shard->strs[idx] = s;
@@ -576,6 +582,29 @@ grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length));
}
+size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) {
+ size_t overhead_and_key = 32 + GPR_SLICE_LENGTH(elem->key->slice);
+ if (is_mdstr_static(elem->value)) {
+ return overhead_and_key + GPR_SLICE_LENGTH(elem->value->slice);
+ } else {
+ internal_string *is = (internal_string *)elem->value;
+ size_t value_len = GPR_SLICE_LENGTH(is->slice);
+ static const uint8_t tail_xtra[3] = {0, 2, 3};
+ if (is->has_size_in_decoder_table == 0) {
+ is->has_size_in_decoder_table = 1;
+ if (grpc_is_binary_header(
+ (const char *)GPR_SLICE_START_PTR(elem->key->slice),
+ GPR_SLICE_LENGTH(elem->key->slice))) {
+ is->size_in_decoder_table =
+ value_len / 3 * 4 + tail_xtra[value_len % 3];
+ } else {
+ is->size_in_decoder_table = value_len;
+ }
+ }
+ return overhead_and_key + is->size_in_decoder_table;
+ }
+}
+
grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
internal_metadata *md = (internal_metadata *)gmd;
if (is_mdelem_static(gmd)) return gmd;