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
9namespace fml {
10
11size_t MessageSerializable::GetSerializableTag() const {
12 return 0;
13};
14
15Message::Message() = default;
16
17Message::~Message() = default;
18
19static 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
35const uint8_t* Message::GetBuffer() const {
36 return buffer_;
37}
38
39size_t Message::GetBufferSize() const {
40 return buffer_length_;
41}
42
43size_t Message::GetDataLength() const {
44 return data_length_;
45}
46
47size_t Message::GetSizeRead() const {
48 return size_read_;
49}
50
51bool Message::Reserve(size_t size) {
52 if (buffer_length_ >= size) {
53 return true;
54 }
55 return Resize(NextPowerOfTwoSize(size));
56}
57
58bool 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
89uint8_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
99uint8_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
108void Message::ResetRead() {
109 size_read_ = 0;
110}
111
112} // namespace fml
113