LMMS
Loading...
Searching...
No Matches
juce_File.cpp
Go to the documentation of this file.
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
23namespace juce
24{
25
26File::File (const String& fullPathName)
27 : fullPath (parseAbsolutePath (fullPathName))
28{
29}
30
32{
33 File f;
34 f.fullPath = path;
35 return f;
36}
37
38File::File (const File& other)
39 : fullPath (other.fullPath)
40{
41}
42
44{
45 fullPath = parseAbsolutePath (newPath);
46 return *this;
47}
48
50{
51 fullPath = other.fullPath;
52 return *this;
53}
54
56 : fullPath (std::move (other.fullPath))
57{
58}
59
60File& File::operator= (File&& other) noexcept
61{
62 fullPath = std::move (other.fullPath);
63 return *this;
64}
65
66//==============================================================================
67static String removeEllipsis (const String& path)
68{
69 // This will quickly find both /../ and /./ at the expense of a minor
70 // false-positive performance hit when path elements end in a dot.
71 #if JUCE_WINDOWS
72 if (path.contains (".\\"))
73 #else
74 if (path.contains ("./"))
75 #endif
76 {
77 StringArray toks;
78 toks.addTokens (path, File::getSeparatorString(), {});
79 bool anythingChanged = false;
80
81 for (int i = 1; i < toks.size(); ++i)
82 {
83 auto& t = toks[i];
84
85 if (t == ".." && toks[i - 1] != "..")
86 {
87 anythingChanged = true;
88 toks.removeRange (i - 1, 2);
89 i = jmax (0, i - 2);
90 }
91 else if (t == ".")
92 {
93 anythingChanged = true;
94 toks.remove (i--);
95 }
96 }
97
98 if (anythingChanged)
100 }
101
102 return path;
103}
104
106{
107 auto normalisedPath = path;
108
109 String separator (File::getSeparatorString());
110 String doubleSeparator (separator + separator);
111
112 auto uncPath = normalisedPath.startsWith (doubleSeparator)
113 && ! normalisedPath.fromFirstOccurrenceOf (doubleSeparator, false, false).startsWith (separator);
114
115 if (uncPath)
116 normalisedPath = normalisedPath.fromFirstOccurrenceOf (doubleSeparator, false, false);
117
118 while (normalisedPath.contains (doubleSeparator))
119 normalisedPath = normalisedPath.replace (doubleSeparator, separator);
120
121 return uncPath ? doubleSeparator + normalisedPath
122 : normalisedPath;
123}
124
125bool File::isRoot() const
126{
127 return fullPath.isNotEmpty() && *this == getParentDirectory();
128}
129
131{
132 if (p.isEmpty())
133 return {};
134
135 #if JUCE_WINDOWS
136 // Windows..
137 auto path = normaliseSeparators (removeEllipsis (p.replaceCharacter ('/', '\\')));
138
139 if (path.startsWithChar (getSeparatorChar()))
140 {
141 if (path[1] != getSeparatorChar())
142 {
143 /* When you supply a raw string to the File object constructor, it must be an absolute path.
144 If you're trying to parse a string that may be either a relative path or an absolute path,
145 you MUST provide a context against which the partial path can be evaluated - you can do
146 this by simply using File::getChildFile() instead of the File constructor. E.g. saying
147 "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
148 path if that's what was supplied, or would evaluate a partial path relative to the CWD.
149 */
151
153 }
154 }
155 else if (! path.containsChar (':'))
156 {
157 /* When you supply a raw string to the File object constructor, it must be an absolute path.
158 If you're trying to parse a string that may be either a relative path or an absolute path,
159 you MUST provide a context against which the partial path can be evaluated - you can do
160 this by simply using File::getChildFile() instead of the File constructor. E.g. saying
161 "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
162 path if that's what was supplied, or would evaluate a partial path relative to the CWD.
163 */
165
167 }
168 #else
169 // Mac or Linux..
170
171 // Yes, I know it's legal for a unix pathname to contain a backslash, but this assertion is here
172 // to catch anyone who's trying to run code that was written on Windows with hard-coded path names.
173 // If that's why you've ended up here, use File::getChildFile() to build your paths instead.
174 jassert ((! p.containsChar ('\\')) || (p.indexOfChar ('/') >= 0 && p.indexOfChar ('/') < p.indexOfChar ('\\')));
175
176 auto path = normaliseSeparators (removeEllipsis (p));
177
178 if (path.startsWithChar ('~'))
179 {
180 if (path[1] == getSeparatorChar() || path[1] == 0)
181 {
182 // expand a name of the form "~/abc"
184 + path.substring (1);
185 }
186 else
187 {
188 // expand a name of type "~dave/abc"
189 auto userName = path.substring (1).upToFirstOccurrenceOf ("/", false, false);
190
191 if (auto* pw = getpwnam (userName.toUTF8()))
192 path = addTrailingSeparator (pw->pw_dir) + path.fromFirstOccurrenceOf ("/", false, false);
193 }
194 }
195 else if (! path.startsWithChar (getSeparatorChar()))
196 {
197 #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS
198 if (! (path.startsWith ("./") || path.startsWith ("../")))
199 {
200 /* When you supply a raw string to the File object constructor, it must be an absolute path.
201 If you're trying to parse a string that may be either a relative path or an absolute path,
202 you MUST provide a context against which the partial path can be evaluated - you can do
203 this by simply using File::getChildFile() instead of the File constructor. E.g. saying
204 "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
205 path if that's what was supplied, or would evaluate a partial path relative to the CWD.
206 */
208
209 #if JUCE_LOG_ASSERTIONS
210 Logger::writeToLog ("Illegal absolute path: " + path);
211 #endif
212 }
213 #endif
214
216 }
217 #endif
218
219 while (path.endsWithChar (getSeparatorChar()) && path != getSeparatorString()) // careful not to turn a single "/" into an empty string.
220 path = path.dropLastCharacters (1);
221
222 return path;
223}
224
226{
227 return path.endsWithChar (getSeparatorChar()) ? path
228 : path + getSeparatorChar();
229}
230
231//==============================================================================
232#if JUCE_LINUX || JUCE_BSD
233 #define NAMES_ARE_CASE_SENSITIVE 1
234#endif
235
237{
238 #if NAMES_ARE_CASE_SENSITIVE
239 return true;
240 #else
241 return false;
242 #endif
243}
244
245static int compareFilenames (const String& name1, const String& name2) noexcept
246{
247 #if NAMES_ARE_CASE_SENSITIVE
248 return name1.compare (name2);
249 #else
250 return name1.compareIgnoreCase (name2);
251 #endif
252}
253
254bool File::operator== (const File& other) const { return compareFilenames (fullPath, other.fullPath) == 0; }
255bool File::operator!= (const File& other) const { return compareFilenames (fullPath, other.fullPath) != 0; }
256bool File::operator< (const File& other) const { return compareFilenames (fullPath, other.fullPath) < 0; }
257bool File::operator> (const File& other) const { return compareFilenames (fullPath, other.fullPath) > 0; }
258
259//==============================================================================
260bool File::setReadOnly (const bool shouldBeReadOnly,
261 const bool applyRecursively) const
262{
263 bool worked = true;
264
265 if (applyRecursively && isDirectory())
266 for (auto& f : findChildFiles (File::findFilesAndDirectories, false))
267 worked = f.setReadOnly (shouldBeReadOnly, true) && worked;
268
269 return setFileReadOnlyInternal (shouldBeReadOnly) && worked;
270}
271
272bool File::setExecutePermission (bool shouldBeExecutable) const
273{
274 return setFileExecutableInternal (shouldBeExecutable);
275}
276
277bool File::deleteRecursively (bool followSymlinks) const
278{
279 bool worked = true;
280
281 if (isDirectory() && (followSymlinks || ! isSymbolicLink()))
282 for (auto& f : findChildFiles (File::findFilesAndDirectories, false))
283 worked = f.deleteRecursively (followSymlinks) && worked;
284
285 return deleteFile() && worked;
286}
287
288bool File::moveFileTo (const File& newFile) const
289{
290 if (newFile.fullPath == fullPath)
291 return true;
292
293 if (! exists())
294 return false;
295
296 #if ! NAMES_ARE_CASE_SENSITIVE
297 if (*this != newFile)
298 #endif
299 if (! newFile.deleteFile())
300 return false;
301
302 return moveInternal (newFile);
303}
304
305bool File::copyFileTo (const File& newFile) const
306{
307 return (*this == newFile)
308 || (exists() && newFile.deleteFile() && copyInternal (newFile));
309}
310
311bool File::replaceFileIn (const File& newFile) const
312{
313 if (newFile.fullPath == fullPath)
314 return true;
315
316 if (! newFile.exists())
317 return moveFileTo (newFile);
318
319 if (! replaceInternal (newFile))
320 return false;
321
322 deleteFile();
323 return true;
324}
325
326bool File::copyDirectoryTo (const File& newDirectory) const
327{
328 if (isDirectory() && newDirectory.createDirectory())
329 {
330 for (auto& f : findChildFiles (File::findFiles, false))
331 if (! f.copyFileTo (newDirectory.getChildFile (f.getFileName())))
332 return false;
333
334 for (auto& f : findChildFiles (File::findDirectories, false))
335 if (! f.copyDirectoryTo (newDirectory.getChildFile (f.getFileName())))
336 return false;
337
338 return true;
339 }
340
341 return false;
342}
343
344//==============================================================================
346{
347 auto lastSlash = fullPath.lastIndexOfChar (getSeparatorChar());
348
349 if (lastSlash > 0)
350 return fullPath.substring (0, lastSlash);
351
352 if (lastSlash == 0)
353 return getSeparatorString();
354
355 return fullPath;
356}
357
362
363//==============================================================================
365{
366 return fullPath.substring (fullPath.lastIndexOfChar (getSeparatorChar()) + 1);
367}
368
370{
371 auto lastSlash = fullPath.lastIndexOfChar (getSeparatorChar()) + 1;
372 auto lastDot = fullPath.lastIndexOfChar ('.');
373
374 if (lastDot > lastSlash)
375 return fullPath.substring (lastSlash, lastDot);
376
377 return fullPath.substring (lastSlash);
378}
379
380bool File::isAChildOf (const File& potentialParent) const
381{
382 if (potentialParent.fullPath.isEmpty())
383 return false;
384
385 auto ourPath = getPathUpToLastSlash();
386
387 if (compareFilenames (potentialParent.fullPath, ourPath) == 0)
388 return true;
389
390 if (potentialParent.fullPath.length() >= ourPath.length())
391 return false;
392
393 return getParentDirectory().isAChildOf (potentialParent);
394}
395
396int File::hashCode() const { return fullPath.hashCode(); }
397int64 File::hashCode64() const { return fullPath.hashCode64(); }
398
399//==============================================================================
401{
402 auto firstChar = *(path.text);
403
404 return firstChar == getSeparatorChar()
405 #if JUCE_WINDOWS
406 || (firstChar != 0 && path.text[1] == ':');
407 #else
408 || firstChar == '~';
409 #endif
410}
411
413{
414 auto r = relativePath.text;
415
416 if (isAbsolutePath (r))
417 return File (String (r));
418
419 #if JUCE_WINDOWS
420 if (r.indexOf ((juce_wchar) '/') >= 0)
421 return getChildFile (String (r).replaceCharacter ('/', '\\'));
422 #endif
423
424 auto path = fullPath;
425 auto separatorChar = getSeparatorChar();
426
427 while (*r == '.')
428 {
429 auto lastPos = r;
430 auto secondChar = *++r;
431
432 if (secondChar == '.') // remove "../"
433 {
434 auto thirdChar = *++r;
435
436 if (thirdChar == separatorChar || thirdChar == 0)
437 {
438 auto lastSlash = path.lastIndexOfChar (separatorChar);
439
440 if (lastSlash >= 0)
441 path = path.substring (0, lastSlash);
442
443 while (*r == separatorChar) // ignore duplicate slashes
444 ++r;
445 }
446 else
447 {
448 r = lastPos;
449 break;
450 }
451 }
452 else if (secondChar == separatorChar || secondChar == 0) // remove "./"
453 {
454 while (*r == separatorChar) // ignore duplicate slashes
455 ++r;
456 }
457 else
458 {
459 r = lastPos;
460 break;
461 }
462 }
463
464 path = addTrailingSeparator (path);
465 path.appendCharPointer (r);
466 return File (path);
467}
468
470{
471 return getParentDirectory().getChildFile (fileName);
472}
473
474//==============================================================================
476{
477 const char* suffix;
478 double divisor = 0;
479
480 if (bytes == 1) { suffix = " byte"; }
481 else if (bytes < 1024) { suffix = " bytes"; }
482 else if (bytes < 1024 * 1024) { suffix = " KB"; divisor = 1024.0; }
483 else if (bytes < 1024 * 1024 * 1024) { suffix = " MB"; divisor = 1024.0 * 1024.0; }
484 else { suffix = " GB"; divisor = 1024.0 * 1024.0 * 1024.0; }
485
486 return (divisor > 0 ? String ((double) bytes / divisor, 1) : String (bytes)) + suffix;
487}
488
489//==============================================================================
491{
492 if (exists())
493 return Result::ok();
494
495 auto parentDir = getParentDirectory();
496
497 if (parentDir == *this)
498 return Result::fail ("Cannot create parent directory");
499
500 auto r = parentDir.createDirectory();
501
502 if (r.wasOk())
503 {
504 FileOutputStream fo (*this, 8);
505 r = fo.getStatus();
506 }
507
508 return r;
509}
510
512{
513 if (isDirectory())
514 return Result::ok();
515
516 auto parentDir = getParentDirectory();
517
518 if (parentDir == *this)
519 return Result::fail ("Cannot create parent directory");
520
521 auto r = parentDir.createDirectory();
522
523 if (r.wasOk())
524 r = createDirectoryInternal (fullPath.trimCharactersAtEnd (getSeparatorString()));
525
526 return r;
527}
528
529//==============================================================================
533
534bool File::setLastModificationTime (Time t) const { return setFileTimesInternal (t.toMilliseconds(), 0, 0); }
535bool File::setLastAccessTime (Time t) const { return setFileTimesInternal (0, t.toMilliseconds(), 0); }
536bool File::setCreationTime (Time t) const { return setFileTimesInternal (0, 0, t.toMilliseconds()); }
537
538//==============================================================================
539bool File::loadFileAsData (MemoryBlock& destBlock) const
540{
541 if (! existsAsFile())
542 return false;
543
544 FileInputStream in (*this);
545 return in.openedOk() && getSize() == (int64) in.readIntoMemoryBlock (destBlock);
546}
547
549{
550 if (! existsAsFile())
551 return {};
552
553 FileInputStream in (*this);
554 return in.openedOk() ? in.readEntireStreamAsString()
555 : String();
556}
557
558void File::readLines (StringArray& destLines) const
559{
560 destLines.addLines (loadFileAsString());
561}
562
563//==============================================================================
564Array<File> File::findChildFiles (int whatToLookFor, bool searchRecursively, const String& wildcard, FollowSymlinks followSymlinks) const
565{
566 Array<File> results;
567 findChildFiles (results, whatToLookFor, searchRecursively, wildcard, followSymlinks);
568 return results;
569}
570
571int File::findChildFiles (Array<File>& results, int whatToLookFor, bool searchRecursively, const String& wildcard, FollowSymlinks followSymlinks) const
572{
573 int total = 0;
574
575 for (const auto& di : RangedDirectoryIterator (*this, searchRecursively, wildcard, whatToLookFor, followSymlinks))
576 {
577 results.add (di.getFile());
578 ++total;
579 }
580
581 return total;
582}
583
584int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const
585{
586 return std::accumulate (RangedDirectoryIterator (*this, false, wildCardPattern, whatToLookFor),
588 0,
589 [] (int acc, const DirectoryEntry&) { return acc + 1; });
590}
591
593{
594 if (! isDirectory())
595 return false;
596
597 return RangedDirectoryIterator (*this, false, "*", findDirectories) != RangedDirectoryIterator();
598}
599
600//==============================================================================
602 const String& suffix,
603 bool putNumbersInBrackets) const
604{
605 auto f = getChildFile (suggestedPrefix + suffix);
606
607 if (f.exists())
608 {
609 int number = 1;
610 auto prefix = suggestedPrefix;
611
612 // remove any bracketed numbers that may already be on the end..
613 if (prefix.trim().endsWithChar (')'))
614 {
615 putNumbersInBrackets = true;
616
617 auto openBracks = prefix.lastIndexOfChar ('(');
618 auto closeBracks = prefix.lastIndexOfChar (')');
619
620 if (openBracks > 0
621 && closeBracks > openBracks
622 && prefix.substring (openBracks + 1, closeBracks).containsOnly ("0123456789"))
623 {
624 number = prefix.substring (openBracks + 1, closeBracks).getIntValue();
625 prefix = prefix.substring (0, openBracks);
626 }
627 }
628
629 do
630 {
631 auto newName = prefix;
632
633 if (putNumbersInBrackets)
634 {
635 newName << '(' << ++number << ')';
636 }
637 else
638 {
639 if (CharacterFunctions::isDigit (prefix.getLastCharacter()))
640 newName << '_'; // pad with an underscore if the name already ends in a digit
641
642 newName << ++number;
643 }
644
645 f = getChildFile (newName + suffix);
646
647 } while (f.exists());
648 }
649
650 return f;
651}
652
653File File::getNonexistentSibling (const bool putNumbersInBrackets) const
654{
655 if (! exists())
656 return *this;
657
658 return getParentDirectory().getNonexistentChildFile (getFileNameWithoutExtension(),
660 putNumbersInBrackets);
661}
662
663//==============================================================================
665{
666 auto indexOfDot = fullPath.lastIndexOfChar ('.');
667
668 if (indexOfDot > fullPath.lastIndexOfChar (getSeparatorChar()))
669 return fullPath.substring (indexOfDot);
670
671 return {};
672}
673
674bool File::hasFileExtension (StringRef possibleSuffix) const
675{
676 if (possibleSuffix.isEmpty())
677 return fullPath.lastIndexOfChar ('.') <= fullPath.lastIndexOfChar (getSeparatorChar());
678
679 auto semicolon = possibleSuffix.text.indexOf ((juce_wchar) ';');
680
681 if (semicolon >= 0)
682 return hasFileExtension (String (possibleSuffix.text).substring (0, semicolon).trimEnd())
683 || hasFileExtension ((possibleSuffix.text + (semicolon + 1)).findEndOfWhitespace());
684
685 if (fullPath.endsWithIgnoreCase (possibleSuffix))
686 {
687 if (possibleSuffix.text[0] == '.')
688 return true;
689
690 auto dotPos = fullPath.length() - possibleSuffix.length() - 1;
691
692 if (dotPos >= 0)
693 return fullPath[dotPos] == '.';
694 }
695
696 return false;
697}
698
700{
701 if (fullPath.isEmpty())
702 return {};
703
704 auto filePart = getFileName();
705
706 auto lastDot = filePart.lastIndexOfChar ('.');
707
708 if (lastDot >= 0)
709 filePart = filePart.substring (0, lastDot);
710
711 if (newExtension.isNotEmpty() && newExtension.text[0] != '.')
712 filePart << '.';
713
714 return getSiblingFile (filePart + newExtension);
715}
716
717//==============================================================================
718bool File::startAsProcess (const String& parameters) const
719{
720 return exists() && Process::openDocument (fullPath, parameters);
721}
722
723//==============================================================================
724std::unique_ptr<FileInputStream> File::createInputStream() const
725{
726 auto fin = std::make_unique<FileInputStream> (*this);
727
728 if (fin->openedOk())
729 return fin;
730
731 return nullptr;
732}
733
734std::unique_ptr<FileOutputStream> File::createOutputStream (size_t bufferSize) const
735{
736 auto fout = std::make_unique<FileOutputStream> (*this, bufferSize);
737
738 if (fout->openedOk())
739 return fout;
740
741 return nullptr;
742}
743
744//==============================================================================
745bool File::appendData (const void* const dataToAppend,
746 const size_t numberOfBytes) const
747{
748 jassert (((ssize_t) numberOfBytes) >= 0);
749
750 if (numberOfBytes == 0)
751 return true;
752
753 FileOutputStream fout (*this, 8192);
754 return fout.openedOk() && fout.write (dataToAppend, numberOfBytes);
755}
756
757bool File::replaceWithData (const void* const dataToWrite,
758 const size_t numberOfBytes) const
759{
760 if (numberOfBytes == 0)
761 return deleteFile();
762
764 tempFile.getFile().appendData (dataToWrite, numberOfBytes);
765 return tempFile.overwriteTargetFileWithTemporary();
766}
767
768bool File::appendText (const String& text, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const
769{
770 FileOutputStream fout (*this);
771
772 if (fout.failedToOpen())
773 return false;
774
775 return fout.writeText (text, asUnicode, writeHeaderBytes, lineFeed);
776}
777
778bool File::replaceWithText (const String& textToWrite, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const
779{
781 tempFile.getFile().appendText (textToWrite, asUnicode, writeHeaderBytes, lineFeed);
782 return tempFile.overwriteTargetFileWithTemporary();
783}
784
785bool File::hasIdenticalContentTo (const File& other) const
786{
787 if (other == *this)
788 return true;
789
790 if (getSize() == other.getSize() && existsAsFile() && other.existsAsFile())
791 {
792 FileInputStream in1 (*this), in2 (other);
793
794 if (in1.openedOk() && in2.openedOk())
795 {
796 const int bufferSize = 4096;
797 HeapBlock<char> buffer1 (bufferSize), buffer2 (bufferSize);
798
799 for (;;)
800 {
801 auto num1 = in1.read (buffer1, bufferSize);
802 auto num2 = in2.read (buffer2, bufferSize);
803
804 if (num1 != num2)
805 break;
806
807 if (num1 <= 0)
808 return true;
809
810 if (memcmp (buffer1, buffer2, (size_t) num1) != 0)
811 break;
812 }
813 }
814 }
815
816 return false;
817}
818
819//==============================================================================
821{
822 auto s = original;
824
825 if (s.isNotEmpty() && s[1] == ':')
826 {
827 start = s.substring (0, 2);
828 s = s.substring (2);
829 }
830
831 return start + s.removeCharacters ("\"#@,;:<>*^|?")
832 .substring (0, 1024);
833}
834
836{
837 auto s = original.removeCharacters ("\"#@,;:<>*^|?\\/");
838
839 const int maxLength = 128; // only the length of the filename, not the whole path
840 auto len = s.length();
841
842 if (len > maxLength)
843 {
844 auto lastDot = s.lastIndexOfChar ('.');
845
846 if (lastDot > jmax (0, len - 12))
847 {
848 s = s.substring (0, maxLength - (len - lastDot))
849 + s.substring (lastDot);
850 }
851 else
852 {
853 s = s.substring (0, maxLength);
854 }
855 }
856
857 return s;
858}
859
860//==============================================================================
861static int countNumberOfSeparators (String::CharPointerType s)
862{
863 int num = 0;
864
865 for (;;)
866 {
867 auto c = s.getAndAdvance();
868
869 if (c == 0)
870 break;
871
872 if (c == File::getSeparatorChar())
873 ++num;
874 }
875
876 return num;
877}
878
880{
881 if (dir == *this)
882 return ".";
883
884 auto thisPath = fullPath;
885
886 while (thisPath.endsWithChar (getSeparatorChar()))
887 thisPath = thisPath.dropLastCharacters (1);
888
890 : dir.fullPath);
891
892 int commonBitLength = 0;
893 auto thisPathAfterCommon = thisPath.getCharPointer();
894 auto dirPathAfterCommon = dirPath.getCharPointer();
895
896 {
897 auto thisPathIter = thisPath.getCharPointer();
898 auto dirPathIter = dirPath.getCharPointer();
899
900 for (int i = 0;;)
901 {
902 auto c1 = thisPathIter.getAndAdvance();
903 auto c2 = dirPathIter.getAndAdvance();
904
905 #if NAMES_ARE_CASE_SENSITIVE
906 if (c1 != c2
907 #else
909 #endif
910 || c1 == 0)
911 break;
912
913 ++i;
914
915 if (c1 == getSeparatorChar())
916 {
917 thisPathAfterCommon = thisPathIter;
918 dirPathAfterCommon = dirPathIter;
919 commonBitLength = i;
920 }
921 }
922 }
923
924 // if the only common bit is the root, then just return the full path..
925 if (commonBitLength == 0 || (commonBitLength == 1 && thisPath[1] == getSeparatorChar()))
926 return fullPath;
927
928 auto numUpDirectoriesNeeded = countNumberOfSeparators (dirPathAfterCommon);
929
930 if (numUpDirectoriesNeeded == 0)
931 return thisPathAfterCommon;
932
933 #if JUCE_WINDOWS
934 auto s = String::repeatedString ("..\\", numUpDirectoriesNeeded);
935 #else
936 auto s = String::repeatedString ("../", numUpDirectoriesNeeded);
937 #endif
938 s.appendCharPointer (thisPathAfterCommon);
939 return s;
940}
941
942//==============================================================================
944{
945 auto tempFile = getSpecialLocation (tempDirectory)
946 .getChildFile ("temp_" + String::toHexString (Random::getSystemRandom().nextInt()))
947 .withFileExtension (fileNameEnding);
948
949 if (tempFile.exists())
950 return createTempFile (fileNameEnding);
951
952 return tempFile;
953}
954
955bool File::createSymbolicLink (const File& linkFileToCreate,
956 const String& nativePathOfTarget,
957 bool overwriteExisting)
958{
959 if (linkFileToCreate.exists())
960 {
961 if (! linkFileToCreate.isSymbolicLink())
962 {
963 // user has specified an existing file / directory as the link
964 // this is bad! the user could end up unintentionally destroying data
966 return false;
967 }
968
969 if (overwriteExisting)
970 linkFileToCreate.deleteFile();
971 }
972
973 #if JUCE_MAC || JUCE_LINUX
974 // one common reason for getting an error here is that the file already exists
975 if (symlink (nativePathOfTarget.toRawUTF8(), linkFileToCreate.getFullPathName().toRawUTF8()) == -1)
976 {
978 return false;
979 }
980
981 return true;
982 #elif JUCE_MSVC
983 File targetFile (linkFileToCreate.getSiblingFile (nativePathOfTarget));
984
985 return CreateSymbolicLink (linkFileToCreate.getFullPathName().toWideCharPointer(),
986 nativePathOfTarget.toWideCharPointer(),
987 targetFile.isDirectory() ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != FALSE;
988 #else
989 ignoreUnused (nativePathOfTarget);
990 jassertfalse; // symbolic links not supported on this platform!
991 return false;
992 #endif
993}
994
995bool File::createSymbolicLink (const File& linkFileToCreate, bool overwriteExisting) const
996{
997 return createSymbolicLink (linkFileToCreate, getFullPathName(), overwriteExisting);
998}
999
1000#if ! JUCE_WINDOWS
1002{
1003 if (isSymbolicLink())
1005
1006 return *this;
1007}
1008#endif
1009
1010//==============================================================================
1011#if JUCE_ALLOW_STATIC_NULL_VARIABLES
1012
1013JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
1015
1016const File File::nonexistent{};
1017
1020
1021#endif
1022
1023//==============================================================================
1029
1030MemoryMappedFile::MemoryMappedFile (const File& file, const Range<int64>& fileRange, AccessMode mode, bool exclusive)
1031 : range (fileRange.getIntersectionWith (Range<int64> (0, file.getSize())))
1032{
1034}
1035
1036
1037//==============================================================================
1038//==============================================================================
1039#if JUCE_UNIT_TESTS
1040
1041class FileTests : public UnitTest
1042{
1043public:
1044 FileTests()
1045 : UnitTest ("Files", UnitTestCategories::files)
1046 {}
1047
1048 void runTest() override
1049 {
1050 beginTest ("Reading");
1051
1054
1055 expect (! File().exists());
1056 expect (! File().existsAsFile());
1057 expect (! File().isDirectory());
1058 #if ! JUCE_WINDOWS
1059 expect (File("/").isDirectory());
1060 #endif
1061 expect (home.isDirectory());
1062 expect (home.exists());
1063 expect (! home.existsAsFile());
1064 expect (File::getSpecialLocation (File::userApplicationDataDirectory).isDirectory());
1066 expect (File::getSpecialLocation (File::currentApplicationFile).exists());
1067 expect (File::getSpecialLocation (File::invokedExecutableFile).exists());
1068 expect (home.getVolumeTotalSize() > 1024 * 1024);
1069 expect (home.getBytesFreeOnVolume() > 0);
1070 expect (! home.isHidden());
1071 expect (home.isOnHardDisk());
1072 expect (! home.isOnCDRomDrive());
1073 expect (File::getCurrentWorkingDirectory().exists());
1074 expect (home.setAsCurrentWorkingDirectory());
1075
1076 {
1077 auto homeParent = home;
1078 bool noSymlinks = true;
1079
1080 while (! homeParent.isRoot())
1081 {
1082 if (homeParent.isSymbolicLink())
1083 {
1084 noSymlinks = false;
1085 break;
1086 }
1087
1088 homeParent = homeParent.getParentDirectory();
1089 }
1090
1091 if (noSymlinks)
1092 expect (File::getCurrentWorkingDirectory() == home);
1093 }
1094
1095 {
1096 Array<File> roots;
1097 File::findFileSystemRoots (roots);
1098 expect (roots.size() > 0);
1099
1100 int numRootsExisting = 0;
1101 for (int i = 0; i < roots.size(); ++i)
1102 if (roots[i].exists())
1103 ++numRootsExisting;
1104
1105 // (on windows, some of the drives may not contain media, so as long as at least one is ok..)
1106 expect (numRootsExisting > 0);
1107 }
1108
1109 beginTest ("Writing");
1110
1111 auto random = getRandom();
1112 const auto tempFolderName = "JUCE UnitTests Temp Folder "
1113 + String::toHexString (random.nextInt())
1114 + ".folder";
1115 File demoFolder (temp.getChildFile (tempFolderName));
1116 expect (demoFolder.deleteRecursively());
1117 expect (demoFolder.createDirectory());
1118 expect (demoFolder.isDirectory());
1119 expect (demoFolder.getParentDirectory() == temp);
1120 expect (temp.isDirectory());
1121 expect (temp.findChildFiles (File::findFilesAndDirectories, false, "*").contains (demoFolder));
1122 expect (temp.findChildFiles (File::findDirectories, true, "*.folder").contains (demoFolder));
1123
1124 File tempFile (demoFolder.getNonexistentChildFile ("test", ".txt", false));
1125
1126 expect (tempFile.getFileExtension() == ".txt");
1127 expect (tempFile.hasFileExtension (".txt"));
1128 expect (tempFile.hasFileExtension ("txt"));
1129 expect (tempFile.withFileExtension ("xyz").hasFileExtension (".xyz"));
1130 expect (tempFile.withFileExtension ("xyz").hasFileExtension ("abc;xyz;foo"));
1131 expect (tempFile.withFileExtension ("xyz").hasFileExtension ("xyz;foo"));
1132 expect (! tempFile.withFileExtension ("h").hasFileExtension ("bar;foo;xx"));
1133 expect (tempFile.getSiblingFile ("foo").isAChildOf (temp));
1134 expect (tempFile.hasWriteAccess());
1135
1136 expect (home.getChildFile (".") == home);
1137 expect (home.getChildFile ("..") == home.getParentDirectory());
1138 expect (home.getChildFile (".xyz").getFileName() == ".xyz");
1139 expect (home.getChildFile ("..xyz").getFileName() == "..xyz");
1140 expect (home.getChildFile ("...xyz").getFileName() == "...xyz");
1141 expect (home.getChildFile ("./xyz") == home.getChildFile ("xyz"));
1142 expect (home.getChildFile ("././xyz") == home.getChildFile ("xyz"));
1143 expect (home.getChildFile ("../xyz") == home.getParentDirectory().getChildFile ("xyz"));
1144 expect (home.getChildFile (".././xyz") == home.getParentDirectory().getChildFile ("xyz"));
1145 expect (home.getChildFile (".././xyz/./abc") == home.getParentDirectory().getChildFile ("xyz/abc"));
1146 expect (home.getChildFile ("./../xyz") == home.getParentDirectory().getChildFile ("xyz"));
1147 expect (home.getChildFile ("a1/a2/a3/./../../a4") == home.getChildFile ("a1/a4"));
1148
1149 expect (! File().hasReadAccess());
1150 expect (! File().hasWriteAccess());
1151
1152 expect (! tempFile.hasReadAccess());
1153
1154 {
1155 FileOutputStream fo (tempFile);
1156 fo.write ("0123456789", 10);
1157 }
1158
1159 expect (tempFile.hasReadAccess());
1160
1161 expect (tempFile.exists());
1162 expect (tempFile.getSize() == 10);
1163 expect (std::abs ((int) (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds())) < 3000);
1164 expectEquals (tempFile.loadFileAsString(), String ("0123456789"));
1165 expect (! demoFolder.containsSubDirectories());
1166
1167 expectEquals (tempFile.getRelativePathFrom (demoFolder.getParentDirectory()), demoFolder.getFileName() + File::getSeparatorString() + tempFile.getFileName());
1168 expectEquals (demoFolder.getParentDirectory().getRelativePathFrom (tempFile), ".." + File::getSeparatorString() + ".." + File::getSeparatorString() + demoFolder.getParentDirectory().getFileName());
1169
1170 expect (demoFolder.getNumberOfChildFiles (File::findFiles) == 1);
1171 expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 1);
1172 expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 0);
1173 demoFolder.getNonexistentChildFile ("tempFolder", "", false).createDirectory();
1174 expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 1);
1175 expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 2);
1176 expect (demoFolder.containsSubDirectories());
1177
1178 expect (tempFile.hasWriteAccess());
1179 tempFile.setReadOnly (true);
1180 expect (! tempFile.hasWriteAccess());
1181 tempFile.setReadOnly (false);
1182 expect (tempFile.hasWriteAccess());
1183
1184 Time t (Time::getCurrentTime());
1185 tempFile.setLastModificationTime (t);
1186 Time t2 = tempFile.getLastModificationTime();
1187 expect (std::abs ((int) (t2.toMilliseconds() - t.toMilliseconds())) <= 1000);
1188
1189 {
1190 MemoryBlock mb;
1191 tempFile.loadFileAsData (mb);
1192 expect (mb.getSize() == 10);
1193 expect (mb[0] == '0');
1194 }
1195
1196 {
1197 expect (tempFile.getSize() == 10);
1198 FileOutputStream fo (tempFile);
1199 expect (fo.openedOk());
1200
1201 expect (fo.setPosition (7));
1202 expect (fo.truncate().wasOk());
1203 expect (tempFile.getSize() == 7);
1204 fo.write ("789", 3);
1205 fo.flush();
1206 expect (tempFile.getSize() == 10);
1207 }
1208
1209 beginTest ("Memory-mapped files");
1210
1211 {
1212 MemoryMappedFile mmf (tempFile, MemoryMappedFile::readOnly);
1213 expect (mmf.getSize() == 10);
1214 expect (mmf.getData() != nullptr);
1215 expect (memcmp (mmf.getData(), "0123456789", 10) == 0);
1216 }
1217
1218 {
1219 const File tempFile2 (tempFile.getNonexistentSibling (false));
1220 expect (tempFile2.create());
1221 expect (tempFile2.appendData ("xxxxxxxxxx", 10));
1222
1223 {
1224 MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite);
1225 expect (mmf.getSize() == 10);
1226 expect (mmf.getData() != nullptr);
1227 memcpy (mmf.getData(), "abcdefghij", 10);
1228 }
1229
1230 {
1231 MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite);
1232 expect (mmf.getSize() == 10);
1233 expect (mmf.getData() != nullptr);
1234 expect (memcmp (mmf.getData(), "abcdefghij", 10) == 0);
1235 }
1236
1237 expect (tempFile2.deleteFile());
1238 }
1239
1240 beginTest ("More writing");
1241
1242 expect (tempFile.appendData ("abcdefghij", 10));
1243 expect (tempFile.getSize() == 20);
1244 expect (tempFile.replaceWithData ("abcdefghij", 10));
1245 expect (tempFile.getSize() == 10);
1246
1247 File tempFile2 (tempFile.getNonexistentSibling (false));
1248 expect (tempFile.copyFileTo (tempFile2));
1249 expect (tempFile2.exists());
1250 expect (tempFile2.hasIdenticalContentTo (tempFile));
1251 expect (tempFile.deleteFile());
1252 expect (! tempFile.exists());
1253 expect (tempFile2.moveFileTo (tempFile));
1254 expect (tempFile.exists());
1255 expect (! tempFile2.exists());
1256
1257 expect (demoFolder.deleteRecursively());
1258 expect (! demoFolder.exists());
1259
1260 {
1261 URL url ("https://audio.dev/foo/bar/");
1262 expectEquals (url.toString (false), String ("https://audio.dev/foo/bar/"));
1263 expectEquals (url.getChildURL ("x").toString (false), String ("https://audio.dev/foo/bar/x"));
1264 expectEquals (url.getParentURL().toString (false), String ("https://audio.dev/foo"));
1265 expectEquals (url.getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));
1266 expectEquals (url.getParentURL().getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));
1267 expectEquals (url.getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/foo/x"));
1268 expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/x"));
1269 }
1270
1271 {
1272 URL url ("https://audio.dev/foo/bar");
1273 expectEquals (url.toString (false), String ("https://audio.dev/foo/bar"));
1274 expectEquals (url.getChildURL ("x").toString (false), String ("https://audio.dev/foo/bar/x"));
1275 expectEquals (url.getParentURL().toString (false), String ("https://audio.dev/foo"));
1276 expectEquals (url.getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));
1277 expectEquals (url.getParentURL().getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));
1278 expectEquals (url.getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/foo/x"));
1279 expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/x"));
1280 }
1281 }
1282};
1283
1284static FileTests fileUnitTests;
1285
1286#endif
1287
1288} // namespace juce
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
#define noexcept
Definition DistrhoDefines.h:72
uint8_t a
Definition Spc_Cpu.h:141
int size() const noexcept
Definition Array.h:187
Definition File.h:50
bool hasFileExtension(StringRef extensionToTest) const
Definition File.cpp:690
bool hasIdenticalContentTo(const File &other) const
Definition File.cpp:795
bool copyDirectoryTo(const File &newDirectory) const
Definition File.cpp:314
int64 getLastAccessTime() const
Definition File.cpp:541
File & operator=(const String &newAbsolutePath)
Definition File.cpp:77
File withFileExtension(StringRef newExtension) const
Definition File.cpp:715
static File createFileWithoutCheckingPath(const String &absolutePath) noexcept
Definition File.cpp:65
static File getCurrentWorkingDirectory()
Definition File.cpp:1395
static File createTempFile(StringRef fileNameEnding)
Definition File.cpp:953
int64 getCreationTime() const
Definition File.cpp:548
bool moveFileTo(const File &targetLocation) const
Definition File.cpp:276
uint getNumberOfChildFiles(int whatToLookFor, const String &wildCardPattern="*") const
Definition File.cpp:597
String getFileExtension() const
Definition File.cpp:680
String getRelativePathFrom(const File &directoryToBeRelativeTo) const
Definition File.cpp:892
int64 getLastModificationTime() const
Definition File.cpp:534
String getPathUpToLastSlash() const
Definition File.cpp:352
File() noexcept
Definition File.cpp:55
bool operator<(const File &) const
Definition File.cpp:256
bool replaceWithData(const void *dataToWrite, size_t numberOfBytes) const
Definition File.cpp:764
static String parseAbsolutePath(const String &)
Definition File.cpp:138
static bool isAbsolutePath(StringRef path)
Definition File.cpp:406
@ findDirectories
Definition File.h:461
@ findFiles
Definition File.h:462
@ findFilesAndDirectories
Definition File.h:463
static String createLegalFileName(const String &fileNameToFix)
Definition File.cpp:848
FileInputStream * createInputStream() const
Definition File.cpp:733
File getNonexistentSibling(bool putNumbersInBrackets=true) const
Definition File.cpp:669
bool deleteRecursively() const
Definition File.cpp:260
bool isAChildOf(const File &potentialParentDirectory) const
Definition File.cpp:389
bool appendText(const String &textToAppend, bool asUnicode=false, bool writeUnicodeHeaderBytes=false) const
Definition File.cpp:775
@ currentExecutableFile
Definition File.h:649
@ userHomeDirectory
Definition File.h:635
@ tempDirectory
Definition File.h:640
static String addTrailingSeparator(const String &path)
Definition File.cpp:225
void readLines(StringArray &destLines) const
Definition File.cpp:575
Result create() const
Definition File.cpp:494
bool loadFileAsData(MemoryBlock &result) const
Definition File.cpp:556
Result createDirectory() const
Definition File.cpp:515
File getChildFile(StringRef relativeOrAbsolutePath) const
Definition File.cpp:418
bool replaceWithText(const String &textToWrite, bool asUnicode=false, bool writeUnicodeHeaderBytes=false) const
Definition File.cpp:786
String getFileNameWithoutExtension() const
Definition File.cpp:378
bool containsSubDirectories() const
Definition File.cpp:607
bool replaceFileIn(const File &targetLocation) const
Definition File.cpp:299
bool createSymbolicLink(const File &linkFileToCreate, bool overwriteExisting) const
Definition File.cpp:965
File getLinkedTarget() const
Definition File.cpp:1610
static bool areFileNamesCaseSensitive()
Definition File.cpp:236
bool operator>(const File &) const
Definition File.cpp:257
bool operator==(const File &) const
Definition File.cpp:254
FileOutputStream * createOutputStream(size_t bufferSize=0x8000) const
Definition File.cpp:743
String getFileName() const
Definition File.cpp:373
bool operator!=(const File &) const
Definition File.cpp:255
bool copyFileTo(const File &targetLocation) const
Definition File.cpp:293
static String descriptionOfSizeInBytes(int64 bytes)
Definition File.cpp:479
File getSiblingFile(StringRef siblingFileName) const
Definition File.cpp:473
String loadFileAsString() const
Definition File.cpp:565
static String createLegalPathName(const String &pathNameToFix)
Definition File.cpp:833
File getParentDirectory() const
Definition File.cpp:365
bool appendData(const void *dataToAppend, size_t numberOfBytes) const
Definition File.cpp:752
static File getSpecialLocation(const SpecialLocationType type)
Definition File.cpp:1642
File getNonexistentChildFile(const String &prefix, const String &suffix, bool putNumbersInBrackets=true) const
Definition File.cpp:617
uint findChildFiles(std::vector< File > &results, int whatToLookFor, bool searchRecursively, const String &wildCardPattern="*") const
Definition File.cpp:581
size_t getSize() const noexcept
Definition MemoryBlock.h:102
static Result ok() noexcept
Definition Result.h:68
static Result fail(const std::string &errorMessage) noexcept
Definition Result.cpp:58
static String toHexString(int number)
Definition String.cpp:1830
static String repeatedString(StringRef stringToRepeat, int numberOfTimesToRepeat)
Definition String.cpp:1028
Definition juce_Array.h:56
void add(const ElementType &newElement)
Definition juce_Array.h:418
static juce_wchar toLowerCase(juce_wchar character) noexcept
Definition juce_CharacterFunctions.cpp:33
static bool isDigit(char character) noexcept
Definition juce_CharacterFunctions.cpp:69
Definition juce_RangedDirectoryIterator.h:36
Definition juce_File.h:45
bool isSymbolicLink() const
Definition juce_linux_CommonFile.cpp:58
bool moveFileTo(const File &targetLocation) const
Definition juce_File.cpp:288
bool copyInternal(const File &) const
Definition juce_linux_CommonFile.cpp:26
int64 hashCode64() const
Definition juce_File.cpp:397
bool isDirectory() const
Definition juce_posix_SharedCode.h:238
Array< File > findChildFiles(int whatToLookFor, bool searchRecursively, const String &wildCardPattern="*", FollowSymlinks followSymlinks=FollowSymlinks::yes) const
Definition juce_File.cpp:564
static StringRef getSeparatorString()
Definition juce_posix_SharedCode.h:114
static String addTrailingSeparator(const String &path)
Definition juce_File.cpp:225
String getFileExtension() const
Definition juce_File.cpp:664
bool existsAsFile() const
Definition juce_posix_SharedCode.h:252
int64 getSize() const
Definition juce_posix_SharedCode.h:257
String fullPath
Definition juce_File.h:1147
const String & getFullPathName() const noexcept
Definition juce_File.h:153
String getFileName() const
Definition juce_File.cpp:364
bool setLastAccessTime(Time newTime) const
Definition juce_File.cpp:535
File getChildFile(StringRef relativeOrAbsolutePath) const
Definition juce_File.cpp:412
String getPathUpToLastSlash() const
Definition juce_File.cpp:345
static bool isAbsolutePath(StringRef path)
Definition juce_File.cpp:400
File getSiblingFile(StringRef siblingFileName) const
Definition juce_File.cpp:469
bool createSymbolicLink(const File &linkFileToCreate, bool overwriteExisting) const
Definition juce_File.cpp:995
static String parseAbsolutePath(const String &)
Definition juce_File.cpp:130
String getFileNameWithoutExtension() const
Definition juce_File.cpp:369
@ tempDirectory
Definition juce_File.h:913
@ userHomeDirectory
Definition juce_File.h:863
bool replaceInternal(const File &) const
Definition juce_posix_SharedCode.h:420
bool appendText(const String &textToAppend, bool asUnicode=false, bool writeUnicodeHeaderBytes=false, const char *lineEndings="\r\n") const
Definition juce_File.cpp:768
int hashCode() const
Definition juce_File.cpp:396
@ findDirectories
Definition juce_File.h:559
@ findFilesAndDirectories
Definition juce_File.h:561
@ findFiles
Definition juce_File.h:560
bool setCreationTime(Time newTime) const
Definition juce_File.cpp:536
bool setReadOnly(bool shouldBeReadOnly, bool applyRecursively=false) const
Definition juce_File.cpp:260
static File createTempFile(StringRef fileNameEnding)
Definition juce_File.cpp:943
static File JUCE_CALLTYPE getSpecialLocation(const SpecialLocationType type)
Definition juce_linux_Files.cpp:107
FollowSymlinks
Definition juce_File.h:566
bool moveInternal(const File &) const
Definition juce_posix_SharedCode.h:404
bool isRoot() const
Definition juce_File.cpp:125
void getFileTimesInternal(int64 &m, int64 &a, int64 &c) const
Definition juce_posix_SharedCode.h:325
bool setFileReadOnlyInternal(bool) const
Definition juce_posix_SharedCode.h:314
String loadFileAsString() const
Definition juce_File.cpp:548
File getParentDirectory() const
Definition juce_File.cpp:358
bool appendData(const void *dataToAppend, size_t numberOfBytes) const
Definition juce_File.cpp:745
bool setExecutePermission(bool shouldBeExecutable) const
Definition juce_File.cpp:272
bool setFileExecutableInternal(bool) const
Definition juce_posix_SharedCode.h:320
bool setFileTimesInternal(int64 m, int64 a, int64 c) const
Definition juce_posix_SharedCode.h:351
static juce_wchar getSeparatorChar()
Definition juce_posix_SharedCode.h:113
File()=default
bool deleteFile() const
Definition juce_posix_SharedCode.h:390
static File createFileWithoutCheckingPath(const String &absolutePath) noexcept
Definition juce_File.cpp:31
bool startAsProcess(const String &parameters=String()) const
Definition juce_File.cpp:718
String getNativeLinkedTarget() const
Definition juce_linux_CommonFile.cpp:63
bool hasFileExtension(StringRef extensionToTest) const
Definition juce_File.cpp:674
bool exists() const
Definition juce_posix_SharedCode.h:246
bool setLastModificationTime(Time newTime) const
Definition juce_File.cpp:534
Result createDirectory() const
Definition juce_File.cpp:511
Result createDirectoryInternal(const String &) const
Definition juce_posix_SharedCode.h:425
Definition juce_FileInputStream.h:35
int read(void *, int) override
Definition juce_FileInputStream.cpp:43
bool openedOk() const noexcept
Definition juce_FileInputStream.h:67
Definition juce_FileOutputStream.h:35
const Result & getStatus() const noexcept
Definition juce_FileOutputStream.h:81
bool write(const void *, size_t) override
Definition juce_FileOutputStream.cpp:76
bool failedToOpen() const noexcept
Definition juce_FileOutputStream.h:86
bool openedOk() const noexcept
Definition juce_FileOutputStream.h:91
Definition juce_HeapBlock.h:87
static void JUCE_CALLTYPE writeToLog(const String &message)
Definition juce_Logger.cpp:40
Definition juce_MemoryBlock.h:33
void openInternal(const File &, AccessMode, bool)
Definition juce_posix_SharedCode.h:560
MemoryMappedFile(const File &file, AccessMode mode, bool exclusive=false)
Definition juce_File.cpp:1024
size_t getSize() const noexcept
Definition juce_MemoryMappedFile.h:94
Range< int64 > range
Definition juce_MemoryMappedFile.h:102
AccessMode
Definition juce_MemoryMappedFile.h:37
virtual bool writeText(const String &text, bool asUTF16, bool writeUTF16ByteOrderMark, const char *lineEndings)
Definition juce_OutputStream.cpp:198
static bool JUCE_CALLTYPE openDocument(const String &documentURL, const String &parameters)
Definition juce_linux_Files.cpp:200
static Random & getSystemRandom() noexcept
Definition juce_Random.cpp:67
Definition juce_Range.h:40
Definition juce_RangedDirectoryIterator.h:100
Definition juce_Result.h:57
Definition juce_StringArray.h:35
String joinIntoString(StringRef separatorString, int startIndex=0, int numberOfElements=-1) const
Definition juce_StringArray.cpp:289
int size() const noexcept
Definition juce_StringArray.h:136
int addLines(StringRef stringToBreakUp)
Definition juce_StringArray.cpp:358
void removeRange(int startIndex, int numberToRemove)
Definition juce_StringArray.cpp:244
void remove(int index)
Definition juce_StringArray.cpp:223
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Definition juce_StringArray.cpp:329
Definition juce_String.h:53
int length() const noexcept
Definition juce_String.cpp:511
bool endsWithChar(juce_wchar character) const noexcept
Definition juce_String.cpp:1410
bool isEmpty() const noexcept
Definition juce_String.h:310
const char * toRawUTF8() const
Definition juce_String.cpp:2074
String removeCharacters(StringRef charactersToRemove) const
Definition juce_String.cpp:1757
bool contains(StringRef text) const noexcept
Definition juce_String.cpp:1035
String trimEnd() const
Definition juce_String.cpp:1687
static String toHexString(IntegerType number)
Definition juce_String.h:1097
const wchar_t * toWideCharPointer() const
Definition juce_String.cpp:2079
String substring(int startIndex, int endIndex) const
Definition juce_String.cpp:1498
Definition juce_StringRef.h:62
bool isNotEmpty() const noexcept
Definition juce_StringRef.h:103
int length() const noexcept
Definition juce_StringRef.h:105
String::CharPointerType text
Definition juce_StringRef.h:130
bool isEmpty() const noexcept
Definition juce_StringRef.h:101
Definition juce_TemporaryFile.h:65
@ useHiddenFile
Definition juce_TemporaryFile.h:70
bool overwriteTargetFileWithTemporary() const
Definition juce_TemporaryFile.cpp:93
const File & getFile() const noexcept
Definition juce_TemporaryFile.h:126
Definition juce_Time.h:37
Definition juce_UnitTest.h:70
File getChildFile(StringRef relativeOrAbsolutePath) const
Definition File.cpp:418
const String & getFullPathName() const noexcept
Definition File.h:152
String substring(int startIndex, int endIndex) const
Definition String.cpp:1373
unsigned * m
Definition inflate.c:1559
struct huft * t
Definition inflate.c:943
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned f
Definition inflate.c:1572
static void c2(register WDL_FFT_COMPLEX *a)
Definition fft.c:270
virtual ASIOError start()=0
#define JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE(...)
Definition juce_CompilerWarnings.h:181
#define JUCE_END_IGNORE_WARNINGS_GCC_LIKE
Definition juce_CompilerWarnings.h:182
#define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings)
Definition juce_CompilerWarnings.h:198
#define JUCE_END_IGNORE_WARNINGS_MSVC
Definition juce_CompilerWarnings.h:199
#define jassert(expression)
#define jassertfalse
float in
Definition lilv_test.c:1460
static char ** files
Definition misc.c:28
Definition juce_UnitTestCategories.h:27
Definition carla_juce.cpp:31
static String normaliseSeparators(const String &path)
Definition juce_File.cpp:105
constexpr Type jmax(Type a, Type b)
Definition juce_MathsFunctions.h:94
long long int64
Definition juce_MathsFunctions.h:54
wchar_t juce_wchar
Definition juce_CharacterFunctions.h:42
void ignoreUnused(Types &&...) noexcept
Definition juce_MathsFunctions.h:333
static int countNumberOfSeparators(String::CharPointerType s)
Definition juce_File.cpp:861
static int compareFilenames(const String &name1, const String &name2) noexcept
Definition juce_File.cpp:245
@ exclusive
Definition juce_audio_devices.h:176
static String removeEllipsis(const String &path)
Definition juce_File.cpp:67
@ Time
Definition LadspaBase.h:49
bool exists(const char *path)
Definition ysfx_utils.cpp:498
png_structrp int mode
Definition png.h:1139
const char * text
Definition swell-functions.h:167
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
memcpy(hh, h, RAND_HEAD_LEN)
int r
Definition crypt.c:458
#define FALSE
Definition unzpriv.h:1298
struct zdirent * file
Definition win32.c:1500
#define const
Definition zconf.h:137