// 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 "impeller/compiler/includer.h" #include #include "flutter/fml/paths.h" namespace impeller { namespace compiler { Includer::Includer(std::shared_ptr working_directory, std::vector include_dirs, std::function on_file_included) : working_directory_(std::move(working_directory)), include_dirs_(std::move(include_dirs)), on_file_included_(std::move(on_file_included)) {} // |shaderc::CompileOptions::IncluderInterface| Includer::~Includer() = default; std::unique_ptr Includer::TryOpenMapping( const IncludeDir& dir, const char* requested_source) { if (!dir.dir || !dir.dir->is_valid()) { return nullptr; } if (requested_source == nullptr) { return nullptr; } std::string source(requested_source); if (source.empty()) { return nullptr; } auto mapping = fml::FileMapping::CreateReadOnly(*dir.dir, requested_source); if (!mapping || !mapping->IsValid()) { return nullptr; } on_file_included_(fml::paths::JoinPaths({dir.name, requested_source})); return mapping; } std::unique_ptr Includer::FindFirstMapping( const char* requested_source) { // Always try the working directory first no matter what the include // directories are. { IncludeDir dir; dir.name = "."; dir.dir = working_directory_; if (auto mapping = TryOpenMapping(dir, requested_source)) { return mapping; } } for (const auto& include_dir : include_dirs_) { if (auto mapping = TryOpenMapping(include_dir, requested_source)) { return mapping; } } return nullptr; } shaderc_include_result* Includer::GetInclude(const char* requested_source, shaderc_include_type type, const char* requesting_source, size_t include_depth) { auto result = std::make_unique(); // Default initialize to failed inclusion. result->source_name = ""; result->source_name_length = 0; constexpr const char* kFileNotFoundMessage = "Included file not found."; result->content = kFileNotFoundMessage; result->content_length = ::strlen(kFileNotFoundMessage); result->user_data = nullptr; if (!working_directory_ || !working_directory_->is_valid()) { return result.release(); } if (requested_source == nullptr) { return result.release(); } auto file = FindFirstMapping(requested_source); if (!file || file->GetMapping() == nullptr) { return result.release(); } auto includer_data = std::make_unique(requested_source, std::move(file)); result->source_name = includer_data->file_name.c_str(); result->source_name_length = includer_data->file_name.length(); result->content = reinterpret_castcontent)>( includer_data->mapping->GetMapping()); result->content_length = includer_data->mapping->GetSize(); result->user_data = includer_data.release(); return result.release(); } void Includer::ReleaseInclude(shaderc_include_result* data) { delete reinterpret_cast(data->user_data); delete data; } } // namespace compiler } // namespace impeller