blob: dc825121663b839bdab8bfd1118f303d36c5f4ef [file] [log] [blame]
John McCutchan3f781b22015-07-23 13:17:00 -07001// Copyright 2015 The Chromium 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 "tonic/dart_library_provider_files.h"
6
7#include "base/bind.h"
8#include "base/files/file_util.h"
9#include "base/strings/string_util.h"
10#include "base/threading/worker_pool.h"
James Robinson94ade6b2015-08-25 13:02:06 -070011#include "mojo/data_pipe_utils/data_pipe_utils.h"
John McCutchan3f781b22015-07-23 13:17:00 -070012#include "tonic/dart_converter.h"
13
14namespace tonic {
15namespace {
16
17void CopyComplete(base::FilePath file, bool success) {
18 if (!success)
19 LOG(ERROR) << "Failed to load " << file.AsUTF8Unsafe();
20}
21
22base::FilePath SimplifyPath(const base::FilePath& path) {
23 std::vector<base::FilePath::StringType> components;
24 path.GetComponents(&components);
25 auto it = components.begin();
26 base::FilePath result(*it++);
27 for (; it != components.end(); it++) {
28 auto& component = *it;
29 if (component == base::FilePath::kCurrentDirectory)
30 continue;
31 if (component == base::FilePath::kParentDirectory)
32 result = result.DirName();
33 else
34 result = result.Append(component);
35 }
36 return result;
37}
38
39} // namespace
40
41DartLibraryProviderFiles::DartLibraryProviderFiles(
42 const base::FilePath& package_root)
43 : package_root_(package_root) {
44 CHECK(base::DirectoryExists(package_root_)) << "Invalid --package-root "
45 << "\"" << package_root_.LossyDisplayName() << "\"";
46}
47
48DartLibraryProviderFiles::~DartLibraryProviderFiles() {
49}
50
51void DartLibraryProviderFiles::GetLibraryAsStream(
52 const std::string& name,
53 DataPipeConsumerCallback callback) {
54 mojo::DataPipe pipe;
55 callback.Run(pipe.consumer_handle.Pass());
56
57 base::FilePath source(name);
58 scoped_refptr<base::TaskRunner> runner =
59 base::WorkerPool::GetTaskRunner(true);
60 mojo::common::CopyFromFile(source, pipe.producer_handle.Pass(), 0,
61 runner.get(), base::Bind(&CopyComplete, source));
62}
63
64std::string DartLibraryProviderFiles::CanonicalizePackageURL(std::string url) {
65 DCHECK(StartsWithASCII(url, "package:", true));
66 ReplaceFirstSubstringAfterOffset(&url, 0, "package:", "");
67 return package_root_.Append(url).AsUTF8Unsafe();
68}
69
70Dart_Handle DartLibraryProviderFiles::CanonicalizeURL(Dart_Handle library,
71 Dart_Handle url) {
72 std::string string = StdStringFromDart(url);
73 if (StartsWithASCII(string, "dart:", true))
74 return url;
75 if (StartsWithASCII(string, "package:", true))
76 return StdStringToDart(CanonicalizePackageURL(string));
77 base::FilePath base_path(StdStringFromDart(Dart_LibraryUrl(library)));
78 base::FilePath resolved_path = base_path.DirName().Append(string);
79 base::FilePath normalized_path = SimplifyPath(resolved_path);
80 return StdStringToDart(normalized_path.AsUTF8Unsafe());
81}
82
83} // namespace tonic