mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
200 lines
4.9 KiB
C++
200 lines
4.9 KiB
C++
// 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/mapping.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <sstream>
|
|
|
|
namespace fml {
|
|
|
|
// FileMapping
|
|
|
|
uint8_t* FileMapping::GetMutableMapping() {
|
|
return mutable_mapping_;
|
|
}
|
|
|
|
std::unique_ptr<FileMapping> FileMapping::CreateReadOnly(
|
|
const std::string& path) {
|
|
return CreateReadOnly(OpenFile(path.c_str(), false, FilePermission::kRead),
|
|
"");
|
|
}
|
|
|
|
std::unique_ptr<FileMapping> FileMapping::CreateReadOnly(
|
|
const fml::UniqueFD& base_fd,
|
|
const std::string& sub_path) {
|
|
if (!sub_path.empty()) {
|
|
return CreateReadOnly(
|
|
OpenFile(base_fd, sub_path.c_str(), false, FilePermission::kRead), "");
|
|
}
|
|
|
|
auto mapping = std::make_unique<FileMapping>(
|
|
base_fd, std::initializer_list<Protection>{Protection::kRead});
|
|
|
|
if (!mapping->IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return mapping;
|
|
}
|
|
|
|
std::unique_ptr<FileMapping> FileMapping::CreateReadExecute(
|
|
const std::string& path) {
|
|
return CreateReadExecute(
|
|
OpenFile(path.c_str(), false, FilePermission::kRead));
|
|
}
|
|
|
|
std::unique_ptr<FileMapping> FileMapping::CreateReadExecute(
|
|
const fml::UniqueFD& base_fd,
|
|
const std::string& sub_path) {
|
|
if (!sub_path.empty()) {
|
|
return CreateReadExecute(
|
|
OpenFile(base_fd, sub_path.c_str(), false, FilePermission::kRead), "");
|
|
}
|
|
|
|
auto mapping = std::make_unique<FileMapping>(
|
|
base_fd, std::initializer_list<Protection>{Protection::kRead,
|
|
Protection::kExecute});
|
|
|
|
if (!mapping->IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return mapping;
|
|
}
|
|
|
|
// Data Mapping
|
|
|
|
DataMapping::DataMapping(std::vector<uint8_t> data) : data_(std::move(data)) {}
|
|
|
|
DataMapping::DataMapping(const std::string& string)
|
|
: data_(string.begin(), string.end()) {}
|
|
|
|
DataMapping::~DataMapping() = default;
|
|
|
|
size_t DataMapping::GetSize() const {
|
|
return data_.size();
|
|
}
|
|
|
|
const uint8_t* DataMapping::GetMapping() const {
|
|
return data_.data();
|
|
}
|
|
|
|
bool DataMapping::IsDontNeedSafe() const {
|
|
return false;
|
|
}
|
|
|
|
// NonOwnedMapping
|
|
NonOwnedMapping::NonOwnedMapping(const uint8_t* data,
|
|
size_t size,
|
|
const ReleaseProc& release_proc,
|
|
bool dontneed_safe)
|
|
: data_(data),
|
|
size_(size),
|
|
release_proc_(release_proc),
|
|
dontneed_safe_(dontneed_safe) {}
|
|
|
|
NonOwnedMapping::~NonOwnedMapping() {
|
|
if (release_proc_) {
|
|
release_proc_(data_, size_);
|
|
}
|
|
}
|
|
|
|
size_t NonOwnedMapping::GetSize() const {
|
|
return size_;
|
|
}
|
|
|
|
const uint8_t* NonOwnedMapping::GetMapping() const {
|
|
return data_;
|
|
}
|
|
|
|
bool NonOwnedMapping::IsDontNeedSafe() const {
|
|
return dontneed_safe_;
|
|
}
|
|
|
|
// MallocMapping
|
|
MallocMapping::MallocMapping() : data_(nullptr), size_(0) {}
|
|
|
|
MallocMapping::MallocMapping(uint8_t* data, size_t size)
|
|
: data_(data), size_(size) {}
|
|
|
|
MallocMapping::MallocMapping(fml::MallocMapping&& mapping)
|
|
: data_(mapping.data_), size_(mapping.size_) {
|
|
mapping.data_ = nullptr;
|
|
mapping.size_ = 0;
|
|
}
|
|
|
|
MallocMapping::~MallocMapping() {
|
|
free(data_);
|
|
data_ = nullptr;
|
|
}
|
|
|
|
MallocMapping MallocMapping::Copy(const void* begin, size_t length) {
|
|
auto result =
|
|
MallocMapping(reinterpret_cast<uint8_t*>(malloc(length)), length);
|
|
FML_CHECK(result.GetMapping() != nullptr);
|
|
memcpy(const_cast<uint8_t*>(result.GetMapping()), begin, length);
|
|
return result;
|
|
}
|
|
|
|
size_t MallocMapping::GetSize() const {
|
|
return size_;
|
|
}
|
|
|
|
const uint8_t* MallocMapping::GetMapping() const {
|
|
return data_;
|
|
}
|
|
|
|
bool MallocMapping::IsDontNeedSafe() const {
|
|
return false;
|
|
}
|
|
|
|
uint8_t* MallocMapping::Release() {
|
|
uint8_t* result = data_;
|
|
data_ = nullptr;
|
|
size_ = 0;
|
|
return result;
|
|
}
|
|
|
|
// Symbol Mapping
|
|
|
|
SymbolMapping::SymbolMapping(fml::RefPtr<fml::NativeLibrary> native_library,
|
|
const char* symbol_name)
|
|
: native_library_(std::move(native_library)) {
|
|
if (native_library_ && symbol_name != nullptr) {
|
|
mapping_ = native_library_->ResolveSymbol(symbol_name);
|
|
|
|
if (mapping_ == nullptr) {
|
|
// Apparently, dart_bootstrap seems to account for the Mac behavior of
|
|
// requiring the underscore prefixed symbol name on non-Mac platforms as
|
|
// well. As a fallback, check the underscore prefixed variant of the
|
|
// symbol name and allow callers to not have handle this on a per platform
|
|
// toolchain quirk basis.
|
|
|
|
std::stringstream underscore_symbol_name;
|
|
underscore_symbol_name << "_" << symbol_name;
|
|
mapping_ =
|
|
native_library_->ResolveSymbol(underscore_symbol_name.str().c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
SymbolMapping::~SymbolMapping() = default;
|
|
|
|
size_t SymbolMapping::GetSize() const {
|
|
return 0;
|
|
}
|
|
|
|
const uint8_t* SymbolMapping::GetMapping() const {
|
|
return mapping_;
|
|
}
|
|
|
|
bool SymbolMapping::IsDontNeedSafe() const {
|
|
return true;
|
|
}
|
|
|
|
} // namespace fml
|