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