• 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_PUBLIC_PB_PACKED_H_
18 #define INCLUDE_PERFETTO_PUBLIC_PB_PACKED_H_
19 
20 #include <stdint.h>
21 #include <string.h>
22 
23 #include "perfetto/public/compiler.h"
24 #include "perfetto/public/pb_msg.h"
25 #include "perfetto/public/pb_utils.h"
26 
27 // This file provides a way of serializing packed repeated fields. All the
28 // strongly typed `struct PerfettoPbPackedMsg*` variants behave as protozero
29 // nested messages and allow zero-copy serialization. A protobuf message that
30 // has a packed repeated field provides begin and end operations that accept a
31 // PerfettoPbPackedMsg. The downside of this approach is that (like all
32 // protozero nested messages), it reserves 4 bytes to encode the length, so it
33 // might add overhead for lots of small messages.
34 
35 // ***
36 // Sample usage of PerfettoPbPackedMsg*
37 // ***
38 // ```
39 // struct PerfettoPbPackedMsgUint64 f;
40 // PROTO_begin_FIELD_NAME(&msg, &f);
41 // PerfettoPbPackedMsgUint64Append(&f, 1);
42 // PerfettoPbPackedMsgUint64Append(&f, 2);
43 // PROTO_end_FIELD_NAME(&msg, &f);
44 // ```
45 
46 // ***
47 // Implementations of struct PerfettoPbPackedMsg for all supported field types.
48 // ***
49 struct PerfettoPbPackedMsgUint64 {
50   struct PerfettoPbMsg msg;
51 };
PerfettoPbPackedMsgUint64Append(struct PerfettoPbPackedMsgUint64 * buf,uint64_t value)52 static inline void PerfettoPbPackedMsgUint64Append(
53     struct PerfettoPbPackedMsgUint64* buf,
54     uint64_t value) {
55   PerfettoPbMsgAppendVarInt(&buf->msg, value);
56 }
57 
58 struct PerfettoPbPackedMsgUint32 {
59   struct PerfettoPbMsg msg;
60 };
PerfettoPbPackedMsgUint32Append(struct PerfettoPbPackedMsgUint32 * buf,uint32_t value)61 static inline void PerfettoPbPackedMsgUint32Append(
62     struct PerfettoPbPackedMsgUint32* buf,
63     uint32_t value) {
64   PerfettoPbMsgAppendVarInt(&buf->msg, value);
65 }
66 
67 struct PerfettoPbPackedMsgInt64 {
68   struct PerfettoPbMsg msg;
69 };
PerfettoPbPackedMsgInt64Append(struct PerfettoPbPackedMsgInt64 * buf,int64_t value)70 static inline void PerfettoPbPackedMsgInt64Append(
71     struct PerfettoPbPackedMsgInt64* buf,
72     int64_t value) {
73   PerfettoPbMsgAppendVarInt(&buf->msg, PERFETTO_STATIC_CAST(uint64_t, value));
74 }
75 
76 struct PerfettoPbPackedMsgInt32 {
77   struct PerfettoPbMsg msg;
78 };
PerfettoPbPackedMsgInt32Append(struct PerfettoPbPackedMsgInt32 * buf,int32_t value)79 static inline void PerfettoPbPackedMsgInt32Append(
80     struct PerfettoPbPackedMsgInt32* buf,
81     int32_t value) {
82   PerfettoPbMsgAppendVarInt(&buf->msg, PERFETTO_STATIC_CAST(uint64_t, value));
83 }
84 
85 struct PerfettoPbPackedMsgSint64 {
86   struct PerfettoPbMsg msg;
87 };
PerfettoPbPackedMsgSint64Append(struct PerfettoPbPackedMsgSint64 * buf,int64_t value)88 static inline void PerfettoPbPackedMsgSint64Append(
89     struct PerfettoPbPackedMsgSint64* buf,
90     int64_t value) {
91   uint64_t encoded = PerfettoPbZigZagEncode64(value);
92   PerfettoPbMsgAppendVarInt(&buf->msg, encoded);
93 }
94 
95 struct PerfettoPbPackedMsgSint32 {
96   struct PerfettoPbMsg msg;
97 };
PerfettoPbPackedMsgSint32Append(struct PerfettoPbPackedMsgSint32 * buf,int32_t value)98 static inline void PerfettoPbPackedMsgSint32Append(
99     struct PerfettoPbPackedMsgSint32* buf,
100     int32_t value) {
101   uint64_t encoded =
102       PerfettoPbZigZagEncode64(PERFETTO_STATIC_CAST(int64_t, value));
103   PerfettoPbMsgAppendVarInt(&buf->msg, encoded);
104 }
105 
106 struct PerfettoPbPackedMsgFixed64 {
107   struct PerfettoPbMsg msg;
108 };
PerfettoPbPackedMsgFixed64Append(struct PerfettoPbPackedMsgFixed64 * buf,uint64_t value)109 static inline void PerfettoPbPackedMsgFixed64Append(
110     struct PerfettoPbPackedMsgFixed64* buf,
111     uint64_t value) {
112   PerfettoPbMsgAppendFixed64(&buf->msg, value);
113 }
114 
115 struct PerfettoPbPackedMsgFixed32 {
116   struct PerfettoPbMsg msg;
117 };
PerfettoPbPackedMsgFixed32Append(struct PerfettoPbPackedMsgFixed32 * buf,uint32_t value)118 static inline void PerfettoPbPackedMsgFixed32Append(
119     struct PerfettoPbPackedMsgFixed32* buf,
120     uint32_t value) {
121   PerfettoPbMsgAppendFixed32(&buf->msg, value);
122 }
123 
124 struct PerfettoPbPackedMsgSfixed64 {
125   struct PerfettoPbMsg msg;
126 };
PerfettoPbPackedMsgSfixed64Append(struct PerfettoPbPackedMsgSfixed64 * buf,int64_t value)127 static inline void PerfettoPbPackedMsgSfixed64Append(
128     struct PerfettoPbPackedMsgSfixed64* buf,
129     int64_t value) {
130   uint64_t encoded;
131   memcpy(&encoded, &value, sizeof(encoded));
132   PerfettoPbMsgAppendFixed64(&buf->msg, encoded);
133 }
134 
135 struct PerfettoPbPackedMsgSfixed32 {
136   struct PerfettoPbMsg msg;
137 };
PerfettoPbPackedMsgSfixed32Append(struct PerfettoPbPackedMsgSfixed32 * buf,int32_t value)138 static inline void PerfettoPbPackedMsgSfixed32Append(
139     struct PerfettoPbPackedMsgSfixed32* buf,
140     int32_t value) {
141   uint32_t encoded;
142   memcpy(&encoded, &value, sizeof(encoded));
143   PerfettoPbMsgAppendFixed32(&buf->msg, encoded);
144 }
145 
146 struct PerfettoPbPackedMsgDouble {
147   struct PerfettoPbMsg msg;
148 };
PerfettoPbPackedMsgDoubleAppend(struct PerfettoPbPackedMsgDouble * buf,double value)149 static inline void PerfettoPbPackedMsgDoubleAppend(
150     struct PerfettoPbPackedMsgDouble* buf,
151     double value) {
152   uint64_t encoded;
153   memcpy(&encoded, &value, sizeof(encoded));
154   PerfettoPbMsgAppendFixed64(&buf->msg, encoded);
155 }
156 
157 struct PerfettoPbPackedMsgFloat {
158   struct PerfettoPbMsg msg;
159 };
PerfettoPbPackedMsgFloatAppend(struct PerfettoPbPackedMsgFloat * buf,float value)160 static inline void PerfettoPbPackedMsgFloatAppend(
161     struct PerfettoPbPackedMsgFloat* buf,
162     float value) {
163   uint32_t encoded;
164   memcpy(&encoded, &value, sizeof(encoded));
165   PerfettoPbMsgAppendFixed32(&buf->msg, encoded);
166 }
167 
168 #endif  // INCLUDE_PERFETTO_PUBLIC_PB_PACKED_H_
169