1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include <string>
12 #include <vector>
13 
14 class CURL;
15 class CAdvancedSettings;
16 
17 class URIUtils
18 {
19 public:
20   static void RegisterAdvancedSettings(const CAdvancedSettings& advancedSettings);
21   static void UnregisterAdvancedSettings();
22 
23   static std::string GetDirectory(const std::string &strFilePath);
24 
25   static std::string GetFileName(const CURL& url);
26   static std::string GetFileName(const std::string& strFileNameAndPath);
27 
28   static std::string GetExtension(const CURL& url);
29   static std::string GetExtension(const std::string& strFileName);
30 
31   /*!
32    \brief Check if there is a file extension
33    \param strFileName Path or URL to check
34    \return \e true if strFileName have an extension.
35    \note Returns false when strFileName is empty.
36    \sa GetExtension
37    */
38   static bool HasExtension(const std::string& strFileName);
39 
40   /*!
41    \brief Check if filename have any of the listed extensions
42    \param strFileName Path or URL to check
43    \param strExtensions List of '.' prefixed lowercase extensions separated with '|'
44    \return \e true if strFileName have any one of the extensions.
45    \note The check is case insensitive for strFileName, but requires
46          strExtensions to be lowercase. Returns false when strFileName or
47          strExtensions is empty.
48    \sa GetExtension
49    */
50   static bool HasExtension(const std::string& strFileName, const std::string& strExtensions);
51   static bool HasExtension(const CURL& url, const std::string& strExtensions);
52 
53   static void RemoveExtension(std::string& strFileName);
54   static std::string ReplaceExtension(const std::string& strFile,
55                                      const std::string& strNewExtension);
56   static void Split(const std::string& strFileNameAndPath,
57                     std::string& strPath, std::string& strFileName);
58   static std::vector<std::string> SplitPath(const std::string& strPath);
59 
60   static void GetCommonPath(std::string& strParent, const std::string& strPath);
61   static std::string GetParentPath(const std::string& strPath);
62   static bool GetParentPath(const std::string& strPath, std::string& strParent);
63 
64   /*! \brief Retrieve the base path, accounting for stacks and files in rars.
65    \param strPath path.
66    \return the folder that contains the item.
67    */
68   static std::string GetBasePath(const std::string& strPath);
69 
70   /* \brief Change the base path of a URL: fromPath/fromFile -> toPath/toFile
71     Handles changes in path separator and filename URL encoding if necessary to derive toFile.
72     \param fromPath the base path of the original URL
73     \param fromFile the filename portion of the original URL
74     \param toPath the base path of the resulting URL
75     \return the full path.
76    */
77   static std::string ChangeBasePath(const std::string &fromPath, const std::string &fromFile, const std::string &toPath, const bool &bAddPath = true);
78 
79   static CURL SubstitutePath(const CURL& url, bool reverse = false);
80   static std::string SubstitutePath(const std::string& strPath, bool reverse = false);
81 
82   /*! \brief Check whether a URL is a given URL scheme.
83    Comparison is case-insensitive as per RFC1738
84    \param url a std::string path.
85    \param type a lower-case scheme name, e.g. "smb".
86    \return true if the url is of the given scheme, false otherwise.
87    \sa PathHasParent, PathEquals
88    */
89   static bool IsProtocol(const std::string& url, const std::string& type);
90 
91   /*! \brief Check whether a path has a given parent.
92    Comparison is case-sensitive.
93    Use IsProtocol() to compare the protocol portion only.
94    \param path a std::string path.
95    \param parent the string the parent of the path should be compared against.
96    \param translate whether to translate any special paths into real paths
97    \return true if the path has the given parent string, false otherwise.
98    \sa IsProtocol, PathEquals
99    */
100   static bool PathHasParent(std::string path, std::string parent, bool translate = false);
101 
102   /*! \brief Check whether a path equals another path.
103    Comparison is case-sensitive.
104    \param path1 a std::string path.
105    \param path2 the second path the path should be compared against.
106    \param ignoreTrailingSlash ignore any trailing slashes in both paths
107    \return true if the paths are equal, false otherwise.
108    \sa IsProtocol, PathHasParent
109    */
110   static bool PathEquals(std::string path1, std::string path2, bool ignoreTrailingSlash = false, bool ignoreURLOptions = false);
111 
112   static bool IsAddonsPath(const std::string& strFile);
113   static bool IsSourcesPath(const std::string& strFile);
114   static bool IsCDDA(const std::string& strFile);
115   static bool IsDAV(const std::string& strFile);
116   static bool IsDOSPath(const std::string &path);
117   static bool IsDVD(const std::string& strFile);
118   static bool IsFTP(const std::string& strFile);
119   static bool IsHTTP(const std::string& strFile);
120   static bool IsUDP(const std::string& strFile);
121   static bool IsTCP(const std::string& strFile);
122   static bool IsHD(const std::string& strFileName);
123   static bool IsInArchive(const std::string& strFile);
124   static bool IsInRAR(const std::string& strFile);
125   static bool IsInternetStream(const std::string& path, bool bStrictCheck = false);
126   static bool IsInternetStream(const CURL& url, bool bStrictCheck = false);
127   static bool IsNetworkFilesystem(const std::string& path);
128   static bool IsInAPK(const std::string& strFile);
129   static bool IsInZIP(const std::string& strFile);
130   static bool IsISO9660(const std::string& strFile);
131   static bool IsLiveTV(const std::string& strFile);
132   static bool IsPVRRecording(const std::string& strFile);
133   static bool IsPVRRecordingFileOrFolder(const std::string& strFile);
134   static bool IsMultiPath(const std::string& strPath);
135   static bool IsMusicDb(const std::string& strFile);
136   static bool IsNfs(const std::string& strFile);
137   static bool IsOnDVD(const std::string& strFile);
138   static bool IsOnLAN(const std::string& strFile);
139   static bool IsHostOnLAN(const std::string& hostName, bool offLineCheck = false);
140   static bool IsPlugin(const std::string& strFile);
141   static bool IsScript(const std::string& strFile);
142   static bool IsRAR(const std::string& strFile);
143   static bool IsRemote(const std::string& strFile);
144   static bool IsSmb(const std::string& strFile);
145   static bool IsSpecial(const std::string& strFile);
146   static bool IsStack(const std::string& strFile);
147   static bool IsUPnP(const std::string& strFile);
148   static bool IsURL(const std::string& strFile);
149   static bool IsVideoDb(const std::string& strFile);
150   static bool IsAPK(const std::string& strFile);
151   static bool IsZIP(const std::string& strFile);
152   static bool IsArchive(const std::string& strFile);
153   static bool IsBluray(const std::string& strFile);
154   static bool IsAndroidApp(const std::string& strFile);
155   static bool IsLibraryFolder(const std::string& strFile);
156   static bool IsLibraryContent(const std::string& strFile);
157   static bool IsPVR(const std::string& strFile);
158   static bool IsPVRChannel(const std::string& strFile);
159   static bool IsPVRChannelGroup(const std::string& strFile);
160   static bool IsPVRGuideItem(const std::string& strFile);
161 
162   static std::string AppendSlash(std::string strFolder);
163   static void AddSlashAtEnd(std::string& strFolder);
164   static bool HasSlashAtEnd(const std::string& strFile, bool checkURL = false);
165   static void RemoveSlashAtEnd(std::string& strFolder);
166   static bool CompareWithoutSlashAtEnd(const std::string& strPath1, const std::string& strPath2);
167   static std::string FixSlashesAndDups(const std::string& path, const char slashCharacter = '/', const size_t startFrom = 0);
168   /**
169    * Convert path to form without duplicated slashes and without relative directories
170    * Strip duplicated slashes
171    * Resolve and remove relative directories ("/../" and "/./")
172    * Will ignore slashes with other direction than specified
173    * Will not resolve path starting from relative directory
174    * @warning Don't use with "protocol://path"-style URLs
175    * @param path string to process
176    * @param slashCharacter character to use as directory delimiter
177    * @return transformed path
178    */
179   static std::string CanonicalizePath(const std::string& path, const char slashCharacter = '\\');
180 
181   static CURL CreateArchivePath(const std::string& type,
182                                 const CURL& archiveUrl,
183                                 const std::string& pathInArchive = "",
184                                 const std::string& password = "");
185 
186   static std::string AddFileToFolder(const std::string& strFolder, const std::string& strFile);
187   template <typename... T>
AddFileToFolder(const std::string & strFolder,const std::string & strFile,T...args)188   static std::string AddFileToFolder(const std::string& strFolder, const std::string& strFile, T... args)
189   {
190     auto newPath = AddFileToFolder(strFolder, strFile);
191     return AddFileToFolder(newPath, args...);
192   }
193 
194   static bool HasParentInHostname(const CURL& url);
195   static bool HasEncodedHostname(const CURL& url);
196   static bool HasEncodedFilename(const CURL& url);
197 
198   /*!
199    \brief Cleans up the given path by resolving "." and ".."
200    and returns it.
201 
202    This methods goes through the given path and removes any "."
203    (as it states "this directory") and resolves any ".." by
204    removing the previous directory from the path. This is done
205    for file paths and host names (in case of VFS paths).
206 
207    \param path Path to be cleaned up
208    \return Actual path without any "." or ".."
209    */
210   static std::string GetRealPath(const std::string &path);
211 
212   /*!
213    \brief Updates the URL encoded hostname of the given path
214 
215    This method must only be used to update paths encoded with
216    the old (Eden) URL encoding implementation to the new (Frodo)
217    URL encoding implementation (which does not URL encode -_.!().
218 
219    \param strFilename Path to update
220    \return True if the path has been updated/changed otherwise false
221    */
222   static bool UpdateUrlEncoding(std::string &strFilename);
223 
224 private:
225   static std::string resolvePath(const std::string &path);
226 
227   static const CAdvancedSettings* m_advancedSettings;
228 };
229 
230