1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
---|---|
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 "flutter/fml/message.h" |
6 | |
7 | #include "flutter/fml/logging.h" |
8 | |
9 | namespace fml { |
10 | |
11 | size_t MessageSerializable::GetSerializableTag() const { |
12 | return 0; |
13 | }; |
14 | |
15 | Message::Message() = default; |
16 | |
17 | Message::~Message() = default; |
18 | |
19 | static uint32_t NextPowerOfTwoSize(uint32_t x) { |
20 | if (x == 0) { |
21 | return 1; |
22 | } |
23 | |
24 | --x; |
25 | |
26 | x |= x >> 1; |
27 | x |= x >> 2; |
28 | x |= x >> 4; |
29 | x |= x >> 8; |
30 | x |= x >> 16; |
31 | |
32 | return x + 1; |
33 | } |
34 | |
35 | const uint8_t* Message::GetBuffer() const { |
36 | return buffer_; |
37 | } |
38 | |
39 | size_t Message::GetBufferSize() const { |
40 | return buffer_length_; |
41 | } |
42 | |
43 | size_t Message::GetDataLength() const { |
44 | return data_length_; |
45 | } |
46 | |
47 | size_t Message::GetSizeRead() const { |
48 | return size_read_; |
49 | } |
50 | |
51 | bool Message::Reserve(size_t size) { |
52 | if (buffer_length_ >= size) { |
53 | return true; |
54 | } |
55 | return Resize(NextPowerOfTwoSize(size)); |
56 | } |
57 | |
58 | bool Message::Resize(size_t size) { |
59 | if (buffer_ == nullptr) { |
60 | // This is the initial resize where we have no previous buffer. |
61 | FML_DCHECK(buffer_length_ == 0); |
62 | |
63 | void* buffer = ::malloc(size); |
64 | const bool success = buffer != nullptr; |
65 | |
66 | if (success) { |
67 | buffer_ = static_cast<uint8_t*>(buffer); |
68 | buffer_length_ = size; |
69 | } |
70 | |
71 | return success; |
72 | } |
73 | |
74 | FML_DCHECK(size > buffer_length_); |
75 | |
76 | void* resized = ::realloc(buffer_, size); |
77 | |
78 | const bool success = resized != nullptr; |
79 | |
80 | // In case of failure, the input buffer to realloc is still valid. |
81 | if (success) { |
82 | buffer_ = static_cast<uint8_t*>(resized); |
83 | buffer_length_ = size; |
84 | } |
85 | |
86 | return success; |
87 | } |
88 | |
89 | uint8_t* Message::PrepareEncode(size_t size) { |
90 | if (!Reserve(data_length_ + size)) { |
91 | return nullptr; |
92 | } |
93 | |
94 | auto old_length = data_length_; |
95 | data_length_ += size; |
96 | return buffer_ + old_length; |
97 | } |
98 | |
99 | uint8_t* Message::PrepareDecode(size_t size) { |
100 | if ((size + size_read_) > buffer_length_) { |
101 | return nullptr; |
102 | } |
103 | auto* buffer = buffer_ + size_read_; |
104 | size_read_ += size; |
105 | return buffer; |
106 | } |
107 | |
108 | void Message::ResetRead() { |
109 | size_read_ = 0; |
110 | } |
111 | |
112 | } // namespace fml |
113 |