xref: /aosp_15_r20/external/perfetto/include/perfetto/public/pb_decoder.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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_DECODER_H_
18 #define INCLUDE_PERFETTO_PUBLIC_PB_DECODER_H_
19 
20 #include "perfetto/public/abi/pb_decoder_abi.h"
21 #include "perfetto/public/compiler.h"
22 #include "perfetto/public/pb_utils.h"
23 
24 // Iterator for parsing protobuf messages.
25 //
26 // Example usage:
27 //
28 // const char* msg_buf = ...
29 // size_t msg_size = ...
30 //
31 // for (struct PerfettoPbDecoderIterator it =
32 //          PerfettoPbDecoderIterateBegin(msg_buf, msg_size);
33 //      it.field.status == PERFETTO_PB_DECODER_OK;
34 //      PerfettoPbDecoderIterateNext(&it)) {
35 //   // Do something with it.field
36 // }
37 struct PerfettoPbDecoderIterator {
38   struct PerfettoPbDecoder decoder;
39   struct PerfettoPbDecoderField field;
40 };
41 
PerfettoPbDecoderIterateBegin(const void * start,size_t size)42 static inline struct PerfettoPbDecoderIterator PerfettoPbDecoderIterateBegin(
43     const void* start,
44     size_t size) {
45   struct PerfettoPbDecoderIterator ret;
46   ret.decoder.read_ptr = PERFETTO_REINTERPRET_CAST(const uint8_t*, start);
47   ret.decoder.end_ptr = PERFETTO_REINTERPRET_CAST(const uint8_t*, start) + size;
48   ret.field = PerfettoPbDecoderParseField(&ret.decoder);
49   return ret;
50 }
51 
52 static inline struct PerfettoPbDecoderIterator
PerfettoPbDecoderIterateNestedBegin(struct PerfettoPbDecoderDelimitedField val)53 PerfettoPbDecoderIterateNestedBegin(
54     struct PerfettoPbDecoderDelimitedField val) {
55   struct PerfettoPbDecoderIterator ret;
56   ret.decoder.read_ptr = val.start;
57   ret.decoder.end_ptr = val.start + val.len;
58   ret.field = PerfettoPbDecoderParseField(&ret.decoder);
59   return ret;
60 }
61 
PerfettoPbDecoderIterateNext(struct PerfettoPbDecoderIterator * iterator)62 static inline void PerfettoPbDecoderIterateNext(
63     struct PerfettoPbDecoderIterator* iterator) {
64   iterator->field = PerfettoPbDecoderParseField(&iterator->decoder);
65 }
66 
PerfettoPbDecoderFieldGetUint32(const PerfettoPbDecoderField * field,uint32_t * out)67 static inline bool PerfettoPbDecoderFieldGetUint32(
68     const PerfettoPbDecoderField* field,
69     uint32_t* out) {
70   switch (field->wire_type) {
71     case PERFETTO_PB_WIRE_TYPE_VARINT:
72     case PERFETTO_PB_WIRE_TYPE_FIXED64:
73       *out = PERFETTO_STATIC_CAST(uint32_t, field->value.integer64);
74       return true;
75     case PERFETTO_PB_WIRE_TYPE_FIXED32:
76       *out = field->value.integer32;
77       return true;
78   }
79   return false;
80 }
81 
PerfettoPbDecoderFieldGetInt32(const PerfettoPbDecoderField * field,int32_t * out)82 static inline bool PerfettoPbDecoderFieldGetInt32(
83     const PerfettoPbDecoderField* field,
84     int32_t* out) {
85   switch (field->wire_type) {
86     case PERFETTO_PB_WIRE_TYPE_VARINT:
87     case PERFETTO_PB_WIRE_TYPE_FIXED64:
88       *out = PERFETTO_STATIC_CAST(int32_t, field->value.integer64);
89       return true;
90     case PERFETTO_PB_WIRE_TYPE_FIXED32:
91       *out = PERFETTO_STATIC_CAST(int32_t, field->value.integer32);
92       return true;
93   }
94   return false;
95 }
96 
PerfettoPbDecoderFieldGetUint64(const PerfettoPbDecoderField * field,uint64_t * out)97 static inline bool PerfettoPbDecoderFieldGetUint64(
98     const PerfettoPbDecoderField* field,
99     uint64_t* out) {
100   switch (field->wire_type) {
101     case PERFETTO_PB_WIRE_TYPE_VARINT:
102     case PERFETTO_PB_WIRE_TYPE_FIXED64:
103       *out = field->value.integer64;
104       return true;
105     case PERFETTO_PB_WIRE_TYPE_FIXED32:
106       *out = field->value.integer32;
107       return true;
108   }
109   return false;
110 }
111 
PerfettoPbDecoderFieldGetInt64(const PerfettoPbDecoderField * field,int64_t * out)112 static inline bool PerfettoPbDecoderFieldGetInt64(
113     const PerfettoPbDecoderField* field,
114     int64_t* out) {
115   switch (field->wire_type) {
116     case PERFETTO_PB_WIRE_TYPE_VARINT:
117     case PERFETTO_PB_WIRE_TYPE_FIXED64:
118       *out = PERFETTO_STATIC_CAST(int64_t, field->value.integer64);
119       return true;
120     case PERFETTO_PB_WIRE_TYPE_FIXED32:
121       *out = PERFETTO_STATIC_CAST(int64_t, field->value.integer32);
122       return true;
123   }
124   return false;
125 }
126 
PerfettoPbDecoderFieldGetBool(const PerfettoPbDecoderField * field,bool * out)127 static inline bool PerfettoPbDecoderFieldGetBool(
128     const PerfettoPbDecoderField* field,
129     bool* out) {
130   switch (field->wire_type) {
131     case PERFETTO_PB_WIRE_TYPE_VARINT:
132     case PERFETTO_PB_WIRE_TYPE_FIXED64:
133       *out = field->value.integer64 != 0;
134       return true;
135     case PERFETTO_PB_WIRE_TYPE_FIXED32:
136       *out = field->value.integer32 != 0;
137       return true;
138   }
139   return false;
140 }
141 
PerfettoPbDecoderFieldGetFloat(const PerfettoPbDecoderField * field,float * out)142 static inline bool PerfettoPbDecoderFieldGetFloat(
143     const PerfettoPbDecoderField* field,
144     float* out) {
145   switch (field->wire_type) {
146     case PERFETTO_PB_WIRE_TYPE_FIXED64:
147       *out = PERFETTO_STATIC_CAST(float, field->value.double_val);
148       return true;
149     case PERFETTO_PB_WIRE_TYPE_FIXED32:
150       *out = field->value.float_val;
151       return true;
152   }
153   return false;
154 }
155 
PerfettoPbDecoderFieldGetDouble(const PerfettoPbDecoderField * field,double * out)156 static inline bool PerfettoPbDecoderFieldGetDouble(
157     const PerfettoPbDecoderField* field,
158     double* out) {
159   switch (field->wire_type) {
160     case PERFETTO_PB_WIRE_TYPE_FIXED64:
161       *out = field->value.double_val;
162       return true;
163     case PERFETTO_PB_WIRE_TYPE_FIXED32:
164       *out = PERFETTO_STATIC_CAST(double, field->value.float_val);
165       return true;
166   }
167   return false;
168 }
169 
170 #endif  // INCLUDE_PERFETTO_PUBLIC_PB_DECODER_H_
171