xref: /aosp_15_r20/external/perfetto/src/protozero/field.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/protozero/field.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/compiler.h"
20*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
21*6dbdd20aSAndroid Build Coastguard Worker 
22*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_IS_LITTLE_ENDIAN()
23*6dbdd20aSAndroid Build Coastguard Worker // The memcpy() for fixed32/64 below needs to be adjusted if we want to
24*6dbdd20aSAndroid Build Coastguard Worker // support big endian CPUs. There doesn't seem to be a compelling need today.
25*6dbdd20aSAndroid Build Coastguard Worker #error Unimplemented for big endian archs.
26*6dbdd20aSAndroid Build Coastguard Worker #endif
27*6dbdd20aSAndroid Build Coastguard Worker 
28*6dbdd20aSAndroid Build Coastguard Worker namespace protozero {
29*6dbdd20aSAndroid Build Coastguard Worker 
30*6dbdd20aSAndroid Build Coastguard Worker template <typename Container>
SerializeAndAppendToInternal(Container * dst) const31*6dbdd20aSAndroid Build Coastguard Worker void Field::SerializeAndAppendToInternal(Container* dst) const {
32*6dbdd20aSAndroid Build Coastguard Worker   namespace pu = proto_utils;
33*6dbdd20aSAndroid Build Coastguard Worker   size_t initial_size = dst->size();
34*6dbdd20aSAndroid Build Coastguard Worker   dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
35*6dbdd20aSAndroid Build Coastguard Worker   uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
36*6dbdd20aSAndroid Build Coastguard Worker   uint8_t* wptr = start;
37*6dbdd20aSAndroid Build Coastguard Worker   switch (type_) {
38*6dbdd20aSAndroid Build Coastguard Worker     case static_cast<int>(pu::ProtoWireType::kVarInt): {
39*6dbdd20aSAndroid Build Coastguard Worker       wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
40*6dbdd20aSAndroid Build Coastguard Worker       wptr = pu::WriteVarInt(int_value_, wptr);
41*6dbdd20aSAndroid Build Coastguard Worker       break;
42*6dbdd20aSAndroid Build Coastguard Worker     }
43*6dbdd20aSAndroid Build Coastguard Worker     case static_cast<int>(pu::ProtoWireType::kFixed32): {
44*6dbdd20aSAndroid Build Coastguard Worker       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
45*6dbdd20aSAndroid Build Coastguard Worker       uint32_t value32 = static_cast<uint32_t>(int_value_);
46*6dbdd20aSAndroid Build Coastguard Worker       memcpy(wptr, &value32, sizeof(value32));
47*6dbdd20aSAndroid Build Coastguard Worker       wptr += sizeof(uint32_t);
48*6dbdd20aSAndroid Build Coastguard Worker       break;
49*6dbdd20aSAndroid Build Coastguard Worker     }
50*6dbdd20aSAndroid Build Coastguard Worker     case static_cast<int>(pu::ProtoWireType::kFixed64): {
51*6dbdd20aSAndroid Build Coastguard Worker       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
52*6dbdd20aSAndroid Build Coastguard Worker       memcpy(wptr, &int_value_, sizeof(int_value_));
53*6dbdd20aSAndroid Build Coastguard Worker       wptr += sizeof(uint64_t);
54*6dbdd20aSAndroid Build Coastguard Worker       break;
55*6dbdd20aSAndroid Build Coastguard Worker     }
56*6dbdd20aSAndroid Build Coastguard Worker     case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
57*6dbdd20aSAndroid Build Coastguard Worker       ConstBytes payload = as_bytes();
58*6dbdd20aSAndroid Build Coastguard Worker       wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
59*6dbdd20aSAndroid Build Coastguard Worker       wptr = pu::WriteVarInt(payload.size, wptr);
60*6dbdd20aSAndroid Build Coastguard Worker       memcpy(wptr, payload.data, payload.size);
61*6dbdd20aSAndroid Build Coastguard Worker       wptr += payload.size;
62*6dbdd20aSAndroid Build Coastguard Worker       break;
63*6dbdd20aSAndroid Build Coastguard Worker     }
64*6dbdd20aSAndroid Build Coastguard Worker     default:
65*6dbdd20aSAndroid Build Coastguard Worker       PERFETTO_FATAL("Unknown field type %u", type_);
66*6dbdd20aSAndroid Build Coastguard Worker   }
67*6dbdd20aSAndroid Build Coastguard Worker   size_t written_size = static_cast<size_t>(wptr - start);
68*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
69*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_DCHECK(initial_size + written_size <= dst->size());
70*6dbdd20aSAndroid Build Coastguard Worker   dst->resize(initial_size + written_size);
71*6dbdd20aSAndroid Build Coastguard Worker }
72*6dbdd20aSAndroid Build Coastguard Worker 
SerializeAndAppendTo(std::string * dst) const73*6dbdd20aSAndroid Build Coastguard Worker void Field::SerializeAndAppendTo(std::string* dst) const {
74*6dbdd20aSAndroid Build Coastguard Worker   SerializeAndAppendToInternal(dst);
75*6dbdd20aSAndroid Build Coastguard Worker }
76*6dbdd20aSAndroid Build Coastguard Worker 
SerializeAndAppendTo(std::vector<uint8_t> * dst) const77*6dbdd20aSAndroid Build Coastguard Worker void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
78*6dbdd20aSAndroid Build Coastguard Worker   SerializeAndAppendToInternal(dst);
79*6dbdd20aSAndroid Build Coastguard Worker }
80*6dbdd20aSAndroid Build Coastguard Worker 
81*6dbdd20aSAndroid Build Coastguard Worker }  // namespace protozero
82