1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "platform_mac.h"
17 
18 #include <CoreFoundation/CFBundle.h>
19 
20 #include <core/io/intf_file_manager.h>
21 #include <core/namespace.h>
22 
23 #include "io/path_tools.h"
24 #include "os/platform.h"
25 #include "util/string_util.h"
26 
27 CORE_BEGIN_NAMESPACE()
28 using BASE_NS::string;
29 using BASE_NS::string_view;
30 
PlatformMac(PlatformCreateInfo const & createInfo)31 PlatformMac::PlatformMac(PlatformCreateInfo const& createInfo)
32 {
33     // Convert the input paths to absolute.
34     auto cwd = GetCurrentDirectory();
35     string_view curPath = cwd;
36 
37     auto fixPath = [&](string_view pathRaw) -> string {
38         if (pathRaw.empty()) {
39             return {};
40         }
41         // fix slashes. (just change \\ to /)
42         string_view pathIn = pathRaw;
43         string tmp;
44         if (pathIn.find("\\") != string_view::npos) {
45             tmp = pathIn;
46             StringUtil::FindAndReplaceAll(tmp, "\\", "/");
47             pathIn = tmp;
48         }
49 
50         string res = "/";
51 
52         string normalizedPath;
53         if (pathIn.empty()) {
54             normalizedPath = curPath;
55         } else {
56             if (pathIn[0] != '/') {
57                 // relative path.
58                 normalizedPath = NormalizePath(curPath + pathIn);
59             } else {
60                 normalizedPath = NormalizePath(pathIn);
61             }
62         }
63         if (normalizedPath.empty()) {
64             // Invalid path? how to handle this?
65             // just fallback on current path for now. (hoping that it's somewhat safe)
66             normalizedPath = curPath;
67         }
68         res += normalizedPath;
69         return string(res.substr(1));
70     };
71 
72     plat_.coreRootPath = fixPath(createInfo.coreRootPath);
73     plat_.appRootPath = fixPath(createInfo.appRootPath);
74     plat_.appPluginPath = fixPath(createInfo.appPluginPath);
75 }
76 
GetPlatformData() const77 const PlatformData& PlatformMac::GetPlatformData() const
78 {
79     return plat_;
80 }
81 
RegisterPluginLocations(IPluginRegister & registry)82 void PlatformMac::RegisterPluginLocations(IPluginRegister& registry)
83 {
84     const BASE_NS::string fileproto("file://");
85     BASE_NS::string pluginDirectory;
86     CFBundleRef main_bundle = CFBundleGetMainBundle();
87     if (main_bundle != NULL) {
88         CFURLRef bundle_url = CFBundleCopyBundleURL(main_bundle);
89         if (bundle_url != NULL) {
90 #ifndef MAXPATHLEN
91 #define MAXPATHLEN 1024
92 #endif
93             char raw_dir[MAXPATHLEN];
94             if (CFURLGetFileSystemRepresentation(bundle_url, true, (UInt8*)raw_dir, MAXPATHLEN)) {
95                 pluginDirectory = fileproto + BASE_NS::string(raw_dir) + "/Contents/PlugIns/";
96             }
97             CFRelease(bundle_url);
98         }
99     }
100 
101     registry.RegisterPluginPath(pluginDirectory);
102     if (!GetPlatformData().appPluginPath.empty()) {
103         registry.RegisterPluginPath(fileproto + GetPlatformData().appPluginPath);
104     }
105 }
106 
Create(PlatformCreateInfo const & createInfo)107 CORE_NS::IPlatform::Ptr Platform::Create(PlatformCreateInfo const& createInfo)
108 {
109     return CORE_NS::IPlatform::Ptr(new PlatformMac(createInfo));
110 }
111 
112 CORE_END_NAMESPACE()
113