• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
18 #define INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
19 
20 #include "perfetto/protozero/message.h"
21 #include "perfetto/protozero/proto_decoder.h"
22 #include "perfetto/protozero/proto_utils.h"
23 #include "perfetto/protozero/scattered_heap_buffer.h"
24 
25 namespace protozero {
26 namespace internal {
27 namespace gen_helpers {
28 
29 // This file implements some helpers used by the protobuf generated code in the
30 // .gen.cc files.
31 //
32 // The .gen.cc generated protobuf implementation (as opposed to the .pbzero.h
33 // implementation) is not zero-copy and is not supposed to be used in fast
34 // paths, so most of these helpers are designed to reduce binary size.
35 
36 void DeserializeString(const protozero::Field& field, std::string* dst);
37 
38 // Read packed repeated elements (serialized as `wire_type`) from `field` into
39 // the `*dst` vector. Returns false if some bytes of `field` could not be
40 // interpreted correctly as `wire_type`.
41 template <proto_utils::ProtoWireType wire_type, typename CppType>
DeserializePackedRepeated(const protozero::Field & field,std::vector<CppType> * dst)42 bool DeserializePackedRepeated(const protozero::Field& field,
43                                std::vector<CppType>* dst) {
44   bool parse_error = false;
45   for (::protozero::PackedRepeatedFieldIterator<wire_type, CppType> rep(
46            field.data(), field.size(), &parse_error);
47        rep; ++rep) {
48     dst->emplace_back(*rep);
49   }
50   return !parse_error;
51 }
52 
53 extern template bool
54 DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, uint64_t>(
55     const protozero::Field& field,
56     std::vector<uint64_t>* dst);
57 
58 extern template bool
59 DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, int64_t>(
60     const protozero::Field& field,
61     std::vector<int64_t>* dst);
62 
63 extern template bool
64 DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, uint32_t>(
65     const protozero::Field& field,
66     std::vector<uint32_t>* dst);
67 
68 extern template bool
69 DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, int32_t>(
70     const protozero::Field& field,
71     std::vector<int32_t>* dst);
72 
73 // Serializers for different type of fields
74 
75 void SerializeTinyVarInt(uint32_t field_id, bool value, Message* msg);
76 
77 template <typename T>
SerializeExtendedVarInt(uint32_t field_id,T value,Message * msg)78 void SerializeExtendedVarInt(uint32_t field_id, T value, Message* msg) {
79   msg->AppendVarInt(field_id, value);
80 }
81 
82 extern template void SerializeExtendedVarInt<uint64_t>(uint32_t field_id,
83                                                        uint64_t value,
84                                                        Message* msg);
85 
86 extern template void SerializeExtendedVarInt<uint32_t>(uint32_t field_id,
87                                                        uint32_t value,
88                                                        Message* msg);
89 
90 template <typename T>
SerializeVarInt(uint32_t field_id,T value,Message * msg)91 void SerializeVarInt(uint32_t field_id, T value, Message* msg) {
92   SerializeExtendedVarInt(
93       field_id, proto_utils::ExtendValueForVarIntSerialization(value), msg);
94 }
95 
96 template <typename T>
SerializeSignedVarInt(uint32_t field_id,T value,Message * msg)97 void SerializeSignedVarInt(uint32_t field_id, T value, Message* msg) {
98   SerializeVarInt(field_id, proto_utils::ZigZagEncode(value), msg);
99 }
100 
101 template <typename T>
SerializeFixed(uint32_t field_id,T value,Message * msg)102 void SerializeFixed(uint32_t field_id, T value, Message* msg) {
103   msg->AppendFixed(field_id, value);
104 }
105 
106 extern template void SerializeFixed<double>(uint32_t field_id,
107                                             double value,
108                                             Message* msg);
109 
110 extern template void SerializeFixed<float>(uint32_t field_id,
111                                            float value,
112                                            Message* msg);
113 
114 extern template void SerializeFixed<uint64_t>(uint32_t field_id,
115                                               uint64_t value,
116                                               Message* msg);
117 
118 extern template void SerializeFixed<int64_t>(uint32_t field_id,
119                                              int64_t value,
120                                              Message* msg);
121 
122 extern template void SerializeFixed<uint32_t>(uint32_t field_id,
123                                               uint32_t value,
124                                               Message* msg);
125 
126 extern template void SerializeFixed<int32_t>(uint32_t field_id,
127                                              int32_t value,
128                                              Message* msg);
129 
130 void SerializeString(uint32_t field_id, const std::string& value, Message* msg);
131 
132 void SerializeUnknownFields(const std::string& unknown_fields, Message* msg);
133 
134 // Wrapper around HeapBuffered that avoids inlining.
135 class MessageSerializer {
136  public:
137   MessageSerializer();
138   ~MessageSerializer();
139 
get()140   Message* get() { return msg_.get(); }
141   std::vector<uint8_t> SerializeAsArray();
142   std::string SerializeAsString();
143 
144  private:
145   HeapBuffered<Message> msg_;
146 };
147 
148 }  // namespace gen_helpers
149 }  // namespace internal
150 }  // namespace protozero
151 
152 #endif  // INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
153