1/*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19#ifndef GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
20#define GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
21
22#include <map>
23
24#include <grpc/impl/codegen/log.h>
25#include <grpcpp/impl/codegen/slice.h>
26
27namespace grpc {
28
29namespace internal {
30
31const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
32
33class MetadataMap {
34 public:
35 MetadataMap() { Setup(); }
36
37 ~MetadataMap() { Destroy(); }
38
39 grpc::string GetBinaryErrorDetails() {
40 // if filled_, extract from the multimap for O(log(n))
41 if (filled_) {
42 auto iter = map_.find(x: kBinaryErrorDetailsKey);
43 if (iter != map_.end()) {
44 return grpc::string(iter->second.begin(), iter->second.length());
45 }
46 }
47 // if not yet filled, take the O(n) lookup to avoid allocating the
48 // multimap until it is requested.
49 // TODO(ncteisen): plumb this through core as a first class object, just
50 // like code and message.
51 else {
52 for (size_t i = 0; i < arr_.count; i++) {
53 if (strncmp(s1: reinterpret_cast<const char*>(
54 GRPC_SLICE_START_PTR(arr_.metadata[i].key)),
55 s2: kBinaryErrorDetailsKey,
56 GRPC_SLICE_LENGTH(arr_.metadata[i].key)) == 0) {
57 return grpc::string(reinterpret_cast<const char*>(
58 GRPC_SLICE_START_PTR(arr_.metadata[i].value)),
59 GRPC_SLICE_LENGTH(arr_.metadata[i].value));
60 }
61 }
62 }
63 return grpc::string();
64 }
65
66 std::multimap<grpc::string_ref, grpc::string_ref>* map() {
67 FillMap();
68 return &map_;
69 }
70 grpc_metadata_array* arr() { return &arr_; }
71
72 void Reset() {
73 filled_ = false;
74 map_.clear();
75 Destroy();
76 Setup();
77 }
78
79 private:
80 bool filled_ = false;
81 grpc_metadata_array arr_;
82 std::multimap<grpc::string_ref, grpc::string_ref> map_;
83
84 void Destroy() {
85 g_core_codegen_interface->grpc_metadata_array_destroy(array: &arr_);
86 }
87
88 void Setup() { memset(s: &arr_, c: 0, n: sizeof(arr_)); }
89
90 void FillMap() {
91 if (filled_) return;
92 filled_ = true;
93 for (size_t i = 0; i < arr_.count; i++) {
94 // TODO(yangg) handle duplicates?
95 map_.insert(x: std::pair<grpc::string_ref, grpc::string_ref>(
96 StringRefFromSlice(slice: &arr_.metadata[i].key),
97 StringRefFromSlice(slice: &arr_.metadata[i].value)));
98 }
99 }
100};
101} // namespace internal
102
103} // namespace grpc
104
105#endif // GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
106

source code of include/grpcpp/impl/codegen/metadata_map.h