• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter 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 "flutter/fml/paths.h"
6 
7 #include <windows.h>
8 #include <algorithm>
9 
10 #include "flutter/fml/paths.h"
11 
12 namespace fml {
13 namespace paths {
14 
15 namespace {
16 
17 constexpr char kFileURLPrefix[] = "file:///";
18 constexpr size_t kFileURLPrefixLength = sizeof(kFileURLPrefix) - 1;
19 
RootLength(const std::string & path)20 size_t RootLength(const std::string& path) {
21   if (path.size() == 0)
22     return 0;
23   if (path[0] == '/')
24     return 1;
25   if (path[0] == '\\') {
26     if (path.size() < 2 || path[1] != '\\')
27       return 1;
28     // The path is a network share. Search for up to two '\'s, as they are
29     // the server and share - and part of the root part.
30     size_t index = path.find('\\', 2);
31     if (index > 0) {
32       index = path.find('\\', index + 1);
33       if (index > 0)
34         return index;
35     }
36     return path.size();
37   }
38   // If the path is of the form 'C:/' or 'C:\', with C being any letter, it's
39   // a root part.
40   if (path.length() >= 2 && path[1] == ':' &&
41       (path[2] == '/' || path[2] == '\\') &&
42       ((path[0] >= 'A' && path[0] <= 'Z') ||
43        (path[0] >= 'a' && path[0] <= 'z'))) {
44     return 3;
45   }
46   return 0;
47 }
48 
LastSeparator(const std::string & path)49 size_t LastSeparator(const std::string& path) {
50   return path.find_last_of("/\\");
51 }
52 
53 }  // namespace
54 
GetExecutableDirectoryPath()55 std::pair<bool, std::string> GetExecutableDirectoryPath() {
56   HMODULE module = GetModuleHandle(NULL);
57   if (module == NULL) {
58     return {false, ""};
59   }
60   char path[MAX_PATH];
61   DWORD read_size = GetModuleFileNameA(module, path, MAX_PATH);
62   if (read_size == 0 || read_size == MAX_PATH) {
63     return {false, ""};
64   }
65   return {true, GetDirectoryName(std::string{path, read_size})};
66 }
67 
AbsolutePath(const std::string & path)68 std::string AbsolutePath(const std::string& path) {
69   char absPath[MAX_PATH];
70   _fullpath(absPath, path.c_str(), MAX_PATH);
71   return std::string(absPath);
72 }
73 
GetDirectoryName(const std::string & path)74 std::string GetDirectoryName(const std::string& path) {
75   size_t rootLength = RootLength(path);
76   size_t separator = LastSeparator(path);
77   if (separator < rootLength)
78     separator = rootLength;
79   if (separator == std::string::npos)
80     return std::string();
81   return path.substr(0, separator);
82 }
83 
FromURI(const std::string & uri)84 std::string FromURI(const std::string& uri) {
85   if (uri.substr(0, kFileURLPrefixLength) != kFileURLPrefix)
86     return uri;
87 
88   std::string file_path = uri.substr(kFileURLPrefixLength);
89   std::replace(file_path.begin(), file_path.end(), '/', '\\');
90   return SanitizeURIEscapedCharacters(file_path);
91 }
92 
GetCachesDirectory()93 fml::UniqueFD GetCachesDirectory() {
94   // Unsupported on this platform.
95   return {};
96 }
97 
98 }  // namespace paths
99 }  // namespace fml
100