1 /*
2  * Copyright (C) 2021 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 #include "perfetto/protozero/message.h"
18 #include "perfetto/protozero/proto_utils.h"
19 
20 #ifndef INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
21 #define INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
22 
23 namespace protozero {
24 namespace internal {
25 
26 template <proto_utils::ProtoSchemaType proto_schema_type>
27 struct FieldWriter {
28   static_assert(proto_schema_type != proto_utils::ProtoSchemaType::kMessage,
29                 "FieldWriter can't be used with nested messages");
30 };
31 
32 template <>
33 struct FieldWriter<proto_utils::ProtoSchemaType::kDouble> {
34   inline static void Append(Message& message, uint32_t field_id, double value) {
35     message.AppendFixed(field_id, value);
36   }
37 };
38 
39 template <>
40 struct FieldWriter<proto_utils::ProtoSchemaType::kFloat> {
41   inline static void Append(Message& message, uint32_t field_id, float value) {
42     message.AppendFixed(field_id, value);
43   }
44 };
45 
46 template <>
47 struct FieldWriter<proto_utils::ProtoSchemaType::kBool> {
48   inline static void Append(Message& message, uint32_t field_id, bool value) {
49     message.AppendTinyVarInt(field_id, value);
50   }
51 };
52 
53 template <>
54 struct FieldWriter<proto_utils::ProtoSchemaType::kInt32> {
55   inline static void Append(Message& message,
56                             uint32_t field_id,
57                             int32_t value) {
58     message.AppendVarInt(field_id, value);
59   }
60 };
61 
62 template <>
63 struct FieldWriter<proto_utils::ProtoSchemaType::kInt64> {
64   inline static void Append(Message& message,
65                             uint32_t field_id,
66                             int64_t value) {
67     message.AppendVarInt(field_id, value);
68   }
69 };
70 
71 template <>
72 struct FieldWriter<proto_utils::ProtoSchemaType::kUint32> {
73   inline static void Append(Message& message,
74                             uint32_t field_id,
75                             uint32_t value) {
76     message.AppendVarInt(field_id, value);
77   }
78 };
79 
80 template <>
81 struct FieldWriter<proto_utils::ProtoSchemaType::kUint64> {
82   inline static void Append(Message& message,
83                             uint32_t field_id,
84                             uint64_t value) {
85     message.AppendVarInt(field_id, value);
86   }
87 };
88 
89 template <>
90 struct FieldWriter<proto_utils::ProtoSchemaType::kSint32> {
91   inline static void Append(Message& message,
92                             uint32_t field_id,
93                             int32_t value) {
94     message.AppendSignedVarInt(field_id, value);
95   }
96 };
97 
98 template <>
99 struct FieldWriter<proto_utils::ProtoSchemaType::kSint64> {
100   inline static void Append(Message& message,
101                             uint32_t field_id,
102                             int64_t value) {
103     message.AppendSignedVarInt(field_id, value);
104   }
105 };
106 
107 template <>
108 struct FieldWriter<proto_utils::ProtoSchemaType::kFixed32> {
109   inline static void Append(Message& message,
110                             uint32_t field_id,
111                             uint32_t value) {
112     message.AppendFixed(field_id, value);
113   }
114 };
115 
116 template <>
117 struct FieldWriter<proto_utils::ProtoSchemaType::kFixed64> {
118   inline static void Append(Message& message,
119                             uint32_t field_id,
120                             uint64_t value) {
121     message.AppendFixed(field_id, value);
122   }
123 };
124 
125 template <>
126 struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed32> {
127   inline static void Append(Message& message,
128                             uint32_t field_id,
129                             int32_t value) {
130     message.AppendFixed(field_id, value);
131   }
132 };
133 
134 template <>
135 struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed64> {
136   inline static void Append(Message& message,
137                             uint32_t field_id,
138                             int64_t value) {
139     message.AppendFixed(field_id, value);
140   }
141 };
142 
143 template <>
144 struct FieldWriter<proto_utils::ProtoSchemaType::kEnum> {
145   template <typename EnumType>
146   inline static void Append(Message& message,
147                             uint32_t field_id,
148                             EnumType value) {
149     message.AppendVarInt(field_id, value);
150   }
151 };
152 
153 template <>
154 struct FieldWriter<proto_utils::ProtoSchemaType::kString> {
155   inline static void Append(Message& message,
156                             uint32_t field_id,
157                             const char* data,
158                             size_t size) {
159     message.AppendBytes(field_id, data, size);
160   }
161 
162   inline static void Append(Message& message,
163                             uint32_t field_id,
164                             const std::string& value) {
165     message.AppendBytes(field_id, value.data(), value.size());
166   }
167 };
168 
169 template <>
170 struct FieldWriter<proto_utils::ProtoSchemaType::kBytes> {
171   inline static void Append(Message& message,
172                             uint32_t field_id,
173                             const uint8_t* data,
174                             size_t size) {
175     message.AppendBytes(field_id, data, size);
176   }
177 
178   inline static void Append(Message& message,
179                             uint32_t field_id,
180                             const std::string& value) {
181     message.AppendBytes(field_id, value.data(), value.size());
182   }
183 };
184 
185 }  // namespace internal
186 }  // namespace protozero
187 
188 #endif  // INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
189