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