// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "flutter/fml/message.h" #include "flutter/fml/logging.h" namespace fml { size_t MessageSerializable::GetSerializableTag() const { return 0; }; Message::Message() = default; Message::~Message() = default; static uint32_t NextPowerOfTwoSize(uint32_t x) { if (x == 0) { return 1; } --x; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return x + 1; } const uint8_t* Message::GetBuffer() const { return buffer_; } size_t Message::GetBufferSize() const { return buffer_length_; } size_t Message::GetDataLength() const { return data_length_; } size_t Message::GetSizeRead() const { return size_read_; } bool Message::Reserve(size_t size) { if (buffer_length_ >= size) { return true; } return Resize(NextPowerOfTwoSize(size)); } bool Message::Resize(size_t size) { if (buffer_ == nullptr) { // This is the initial resize where we have no previous buffer. FML_DCHECK(buffer_length_ == 0); void* buffer = ::malloc(size); const bool success = buffer != nullptr; if (success) { buffer_ = static_cast(buffer); buffer_length_ = size; } return success; } FML_DCHECK(size > buffer_length_); void* resized = ::realloc(buffer_, size); const bool success = resized != nullptr; // In case of failure, the input buffer to realloc is still valid. if (success) { buffer_ = static_cast(resized); buffer_length_ = size; } return success; } uint8_t* Message::PrepareEncode(size_t size) { if (!Reserve(data_length_ + size)) { return nullptr; } auto old_length = data_length_; data_length_ += size; return buffer_ + old_length; } uint8_t* Message::PrepareDecode(size_t size) { if ((size + size_read_) > buffer_length_) { return nullptr; } auto* buffer = buffer_ + size_read_; size_read_ += size; return buffer; } void Message::ResetRead() { size_read_ = 0; } } // namespace fml