🌐 AI搜索 & 代理 主页
blob: 4cd9f2fd45676c8cc4566ac4ed96e3f5909c04ea [file] [log] [blame]
Alex Gough5033b85d2024-03-27 21:29:221// Copyright 2024 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "mojo/public/cpp/base/proto_wrapper.h"
6
7#include <limits>
8
9#include "base/check_op.h"
Tom Sepez84bfab32025-07-28 23:47:4010#include "base/compiler_specific.h"
Alex Gough5033b85d2024-03-27 21:29:2211#include "third_party/protobuf/src/google/protobuf/message_lite.h"
12
13namespace mojo_base {
14
15ProtoWrapper::ProtoWrapper() = default;
16ProtoWrapper::ProtoWrapper(mojo::DefaultConstruct::Tag passkey) {}
17ProtoWrapper::~ProtoWrapper() = default;
18ProtoWrapper::ProtoWrapper(ProtoWrapper&& other) = default;
19ProtoWrapper& ProtoWrapper::operator=(ProtoWrapper&& other) = default;
20
21ProtoWrapper::ProtoWrapper(const google::protobuf::MessageLite& message) {
22 proto_name_ = message.GetTypeName();
23 CHECK(message.ByteSizeLong() <= std::numeric_limits<int>::max());
24 bytes_ = BigBuffer(message.ByteSizeLong());
25 CHECK(message.SerializeToArray(bytes_->data(), bytes_->size()));
26}
27
28ProtoWrapper::ProtoWrapper(base::span<const uint8_t> data,
29 std::string type_name,
30 base::PassKey<ProtoWrapperBytes> passkey) {
31 CHECK(!type_name.empty());
32 CHECK_GT(data.size(), 0u);
33 // Protobuf's unwrapping mechanisms take `int`.
34 CHECK_LT(data.size(), static_cast<size_t>(std::numeric_limits<int>::max()));
35
36 bytes_ = BigBuffer(data);
37 proto_name_ = type_name;
38}
39
40bool ProtoWrapper::DeserializeToMessage(
Joe Masona7594652024-09-18 19:12:1741 google::protobuf::MessageLite& message) const {
Alex Gough5033b85d2024-03-27 21:29:2242 if (!bytes_.has_value()) {
43 return false;
44 }
45 // ProtoWrapper is either constructed from a message or from a mojom
46 // typemapping, so must have a typename.
47 if (message.GetTypeName() != proto_name_) {
48 return false;
49 }
50 // ParseFromArray can only take `int`.
51 if (bytes_->size() > std::numeric_limits<int>::max()) {
52 return false;
53 }
54
55 if (bytes_->storage_type() == BigBuffer::StorageType::kBytes) {
56 return message.ParseFromArray(bytes_->data(), bytes_->size());
57 } else {
58 // Make an in-process copy here as protobuf is not designed to
59 // safely parse data that might be changing underneath it.
Tom Sepez84bfab32025-07-28 23:47:4060 auto as_span = UNSAFE_TODO(base::span(bytes_->data(), bytes_->size()));
Jose Dapena Paz0bed9a52024-04-16 10:59:0861 const std::vector<uint8_t> copy(as_span.begin(), as_span.end());
Alex Gough5033b85d2024-03-27 21:29:2262 return message.ParseFromArray(copy.data(), copy.size());
63 }
64}
65
66} // namespace mojo_base