blob: 1b5e78c4d5947711a87db40c6132fbed3e7e73a9 [file] [log] [blame]
// Copyright 2015 The Chromium 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 "sky/shell/dart/dart_library_provider_files.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "base/threading/worker_pool.h"
#include "mojo/data_pipe_utils/data_pipe_utils.h"
#include "sky/engine/tonic/dart_converter.h"
namespace sky {
namespace shell {
namespace {
void CopyComplete(base::FilePath file, bool success) {
if (!success)
LOG(ERROR) << "Failed to load " << file.AsUTF8Unsafe();
}
base::FilePath SimplifyPath(const base::FilePath& path) {
std::vector<base::FilePath::StringType> components;
path.GetComponents(&components);
auto it = components.begin();
base::FilePath result(*it++);
for (; it != components.end(); it++) {
auto& component = *it;
if (component == base::FilePath::kCurrentDirectory)
continue;
if (component == base::FilePath::kParentDirectory)
result = result.DirName();
else
result = result.Append(component);
}
return result;
}
} // namespace
DartLibraryProviderFiles::DartLibraryProviderFiles(
const base::FilePath& package_root)
: package_root_(package_root) {
if (package_root_.empty())
package_root_ = base::FilePath(FILE_PATH_LITERAL("packages"));
if (!base::DirectoryExists(package_root_))
package_root_ = base::FilePath();
}
DartLibraryProviderFiles::~DartLibraryProviderFiles() {
}
void DartLibraryProviderFiles::GetLibraryAsStream(
const std::string& name,
blink::DataPipeConsumerCallback callback) {
mojo::DataPipe pipe;
callback.Run(pipe.consumer_handle.Pass());
base::FilePath source(name);
scoped_refptr<base::TaskRunner> runner =
base::WorkerPool::GetTaskRunner(true);
mojo::common::CopyFromFile(source, pipe.producer_handle.Pass(), 0,
runner.get(), base::Bind(&CopyComplete, source));
}
std::string DartLibraryProviderFiles::CanonicalizePackageURL(std::string url) {
DCHECK(base::StartsWithASCII(url, "package:", true));
base::ReplaceFirstSubstringAfterOffset(&url, 0, "package:", "");
CHECK(!package_root_.empty())
<< "Cannot import packages without a valid --package-root";
return package_root_.Append(url).AsUTF8Unsafe();
}
std::string DartLibraryProviderFiles::CanonicalizeFileURL(std::string url) {
DCHECK(base::StartsWithASCII(url, "file:", true));
base::ReplaceFirstSubstringAfterOffset(&url, 0, "file:", "");
return url;
}
Dart_Handle DartLibraryProviderFiles::CanonicalizeURL(Dart_Handle library,
Dart_Handle url) {
std::string string = blink::StdStringFromDart(url);
if (base::StartsWithASCII(string, "dart:", true))
return url;
if (base::StartsWithASCII(string, "package:", true))
return blink::StdStringToDart(CanonicalizePackageURL(string));
if (base::StartsWithASCII(string, "file:", true))
return blink::StdStringToDart(CanonicalizeFileURL(string));
base::FilePath base_path(blink::StdStringFromDart(Dart_LibraryUrl(library)));
base::FilePath resolved_path = base_path.DirName().Append(string);
base::FilePath normalized_path = SimplifyPath(resolved_path);
return blink::StdStringToDart(normalized_path.AsUTF8Unsafe());
}
} // namespace shell
} // namespace sky