• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_PYTHON_OPENCENSUS_RPC_ENCODING_H
16 #define GRPC_PYTHON_OPENCENSUS_RPC_ENCODING_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <stdint.h>
21 #include <string.h>
22 
23 #include "absl/base/internal/endian.h"
24 #include "absl/strings/string_view.h"
25 
26 namespace grpc_observability {
27 
28 // TODO(xuanwn): Reuse c++ rpc_encoding file.
29 // RpcServerStatsEncoding encapsulates the logic for encoding and decoding of
30 // rpc server stats messages. Rpc server stats consists of a uint64_t time
31 // value (server latency in nanoseconds).
32 class RpcServerStatsEncoding {
33  public:
34   // Size of encoded RPC server stats.
35   static constexpr size_t kRpcServerStatsSize = 10;
36   // Error value.
37   static constexpr size_t kEncodeDecodeFailure = 0;
38 
39   // Deserializes rpc server stats from the incoming 'buf' into *time.  Returns
40   // number of bytes decoded. If the buffer is of insufficient size (it must be
41   // at least kRpcServerStatsSize bytes) or the encoding version or field ID are
42   // unrecognized, *time will be set to 0 and it will return
43   // kEncodeDecodeFailure. Inlined for performance reasons.
Decode(absl::string_view buf,uint64_t * time)44   static size_t Decode(absl::string_view buf, uint64_t* time) {
45     if (buf.size() < kRpcServerStatsSize) {
46       *time = 0;
47       return kEncodeDecodeFailure;
48     }
49 
50     uint8_t version = buf[kVersionIdOffset];
51     uint32_t fieldID = buf[kServerElapsedTimeOffset];
52     if (version != kVersionId || fieldID != kServerElapsedTimeField) {
53       *time = 0;
54       return kEncodeDecodeFailure;
55     }
56     *time = absl::little_endian::Load64(
57         &buf[kServerElapsedTimeOffset + kFieldIdSize]);
58     return kRpcServerStatsSize;
59   }
60 
61   // Serializes rpc server stats into the provided buffer.  It returns the
62   // number of bytes written to the buffer. If the buffer is smaller than
63   // kRpcServerStatsSize bytes it will return kEncodeDecodeFailure. Inlined for
64   // performance reasons.
Encode(uint64_t time,char * buf,size_t buf_size)65   static size_t Encode(uint64_t time, char* buf, size_t buf_size) {
66     if (buf_size < kRpcServerStatsSize) {
67       return kEncodeDecodeFailure;
68     }
69 
70     buf[kVersionIdOffset] = kVersionId;
71     buf[kServerElapsedTimeOffset] = kServerElapsedTimeField;
72     absl::little_endian::Store64(&buf[kServerElapsedTimeOffset + kFieldIdSize],
73                                  time);
74     return kRpcServerStatsSize;
75   }
76 
77  private:
78   // Size of Version ID.
79   static constexpr size_t kVersionIdSize = 1;
80   // Size of Field ID.
81   static constexpr size_t kFieldIdSize = 1;
82 
83   // Offset and value for currently supported version ID.
84   static constexpr size_t kVersionIdOffset = 0;
85   static constexpr size_t kVersionId = 0;
86 
87   enum FieldIdValue {
88     kServerElapsedTimeField = 0,
89   };
90 
91   enum FieldSize {
92     kServerElapsedTimeSize = 8,
93   };
94 
95   enum FieldIdOffset {
96     kServerElapsedTimeOffset = kVersionIdSize,
97   };
98 
99   RpcServerStatsEncoding() = delete;
100   RpcServerStatsEncoding(const RpcServerStatsEncoding&) = delete;
101   RpcServerStatsEncoding(RpcServerStatsEncoding&&) = delete;
102   RpcServerStatsEncoding operator=(const RpcServerStatsEncoding&) = delete;
103   RpcServerStatsEncoding operator=(RpcServerStatsEncoding&&) = delete;
104 };
105 
106 }  // namespace grpc_observability
107 
108 #endif  // GRPC_PYTHON_OPENCENSUS_RPC_ENCODING_H
109