OpenShot Audio Library | OpenShotAudio  0.6.0
juce_FileSearchPath.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
27 {
28  init (path);
29 }
30 
32  : directories (other.directories)
33 {
34 }
35 
37 {
38  directories = other.directories;
39  return *this;
40 }
41 
43 {
44  init (path);
45  return *this;
46 }
47 
48 void FileSearchPath::init (const String& path)
49 {
50  directories.clear();
51  directories.addTokens (path, ";", "\"");
52  directories.trim();
53  directories.removeEmptyStrings();
54 
55  for (auto& d : directories)
56  d = d.unquoted();
57 }
58 
60 {
61  return directories.size();
62 }
63 
65 {
66  return File (getRawString (index));
67 }
68 
70 {
71  return directories[index];
72 }
73 
75 {
76  return toStringWithSeparator (";");
77 }
78 
80 {
81  auto dirs = directories;
82 
83  for (auto& d : dirs)
84  if (d.contains (separator))
85  d = d.quoted();
86 
87  return dirs.joinIntoString (separator);
88 }
89 
90 void FileSearchPath::add (const File& dir, int insertIndex)
91 {
92  directories.insert (insertIndex, dir.getFullPathName());
93 }
94 
96 {
97  for (auto& d : directories)
98  if (File (d) == dir)
99  return false;
100 
101  add (dir);
102  return true;
103 }
104 
105 void FileSearchPath::remove (int index)
106 {
107  directories.remove (index);
108 }
109 
111 {
112  for (int i = 0; i < other.getNumPaths(); ++i)
113  addIfNotAlreadyThere (other[i]);
114 }
115 
117 {
118  std::vector<String> reduced;
119 
120  for (const auto& directory : directories)
121  {
122  const auto checkedIsChildOf = [&] (const auto& a, const auto& b)
123  {
124  return File::isAbsolutePath (a) && File::isAbsolutePath (b) && File (a).isAChildOf (b);
125  };
126 
127  const auto fContainsDirectory = [&] (const auto& f)
128  {
129  return f == directory || checkedIsChildOf (directory, f);
130  };
131 
132  if (std::find_if (reduced.begin(), reduced.end(), fContainsDirectory) != reduced.end())
133  continue;
134 
135  const auto directoryContainsF = [&] (const auto& f) { return checkedIsChildOf (f, directory); };
136 
137  reduced.erase (std::remove_if (reduced.begin(), reduced.end(), directoryContainsF), reduced.end());
138  reduced.push_back (directory);
139  }
140 
141  directories = StringArray (reduced.data(), (int) reduced.size());
142 }
143 
145 {
146  for (int i = directories.size(); --i >= 0;)
147  if (! File (directories[i]).isDirectory())
148  directories.remove (i);
149 }
150 
151 Array<File> FileSearchPath::findChildFiles (int whatToLookFor, bool recurse, const String& wildcard) const
152 {
153  Array<File> results;
154  findChildFiles (results, whatToLookFor, recurse, wildcard);
155  return results;
156 }
157 
158 int FileSearchPath::findChildFiles (Array<File>& results, int whatToLookFor,
159  bool recurse, const String& wildcard) const
160 {
161  int total = 0;
162 
163  for (auto& d : directories)
164  total += File (d).findChildFiles (results, whatToLookFor, recurse, wildcard);
165 
166  return total;
167 }
168 
169 bool FileSearchPath::isFileInPath (const File& fileToCheck,
170  const bool checkRecursively) const
171 {
172  for (auto& d : directories)
173  {
174  if (checkRecursively)
175  {
176  if (fileToCheck.isAChildOf (File (d)))
177  return true;
178  }
179  else
180  {
181  if (fileToCheck.getParentDirectory() == File (d))
182  return true;
183  }
184  }
185 
186  return false;
187 }
188 
189 //==============================================================================
190 //==============================================================================
191 #if JUCE_UNIT_TESTS
192 
193 class FileSearchPathTests final : public UnitTest
194 {
195 public:
196  FileSearchPathTests() : UnitTest ("FileSearchPath", UnitTestCategories::files) {}
197 
198  void runTest() override
199  {
200  beginTest ("removeRedundantPaths");
201  {
202  #if JUCE_WINDOWS
203  const String prefix = "C:";
204  #else
205  const String prefix = "";
206  #endif
207 
208  {
209  FileSearchPath fsp { prefix + "/a/b/c/d;" + prefix + "/a/b/c/e;" + prefix + "/a/b/c" };
210  fsp.removeRedundantPaths();
211  expectEquals (fsp.toString(), prefix + "/a/b/c");
212  }
213 
214  {
215  FileSearchPath fsp { prefix + "/a/b/c;" + prefix + "/a/b/c/d;" + prefix + "/a/b/c/e" };
216  fsp.removeRedundantPaths();
217  expectEquals (fsp.toString(), prefix + "/a/b/c");
218  }
219 
220  {
221  FileSearchPath fsp { prefix + "/a/b/c/d;" + prefix + "/a/b/c;" + prefix + "/a/b/c/e" };
222  fsp.removeRedundantPaths();
223  expectEquals (fsp.toString(), prefix + "/a/b/c");
224  }
225 
226  {
227  FileSearchPath fsp { "%FOO%;" + prefix + "/a/b/c;%FOO%;" + prefix + "/a/b/c/d" };
228  fsp.removeRedundantPaths();
229  expectEquals (fsp.toString(), "%FOO%;" + prefix + "/a/b/c");
230  }
231  }
232  }
233 };
234 
235 static FileSearchPathTests fileSearchPathTests;
236 
237 #endif
238 
239 } // namespace juce
bool isFileInPath(const File &fileToCheck, bool checkRecursively) const
void add(const File &directoryToAdd, int insertIndex=-1)
void remove(int indexToRemove)
FileSearchPath & operator=(const FileSearchPath &)
void addPath(const FileSearchPath &)
File operator[](int index) const
FileSearchPath()=default
bool addIfNotAlreadyThere(const File &directoryToAdd)
String toStringWithSeparator(StringRef separator) const
Array< File > findChildFiles(int whatToLookFor, bool searchRecursively, const String &wildCardPattern="*") const
String getRawString(int index) const
Array< File > findChildFiles(int whatToLookFor, bool searchRecursively, const String &wildCardPattern="*", FollowSymlinks followSymlinks=FollowSymlinks::yes) const
Definition: juce_File.cpp:572
const String & getFullPathName() const noexcept
Definition: juce_File.h:153
static bool isAbsolutePath(StringRef path)
Definition: juce_File.cpp:408
File getParentDirectory() const
Definition: juce_File.cpp:358
bool isAChildOf(const File &potentialParentDirectory) const
Definition: juce_File.cpp:388
void removeEmptyStrings(bool removeWhitespaceStrings=true)
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
String quoted(juce_wchar quoteCharacter='"') const