| @@ -106,6 +106,7 @@ OBJECTS := \ | |||
| $(OBJDIR)/juce_Logger_4f4f7f72.o \ | |||
| $(OBJDIR)/juce_PerformanceCounter_6422080e.o \ | |||
| $(OBJDIR)/juce_RelativeTime_bc5ef35b.o \ | |||
| $(OBJDIR)/juce_Result_d8f437f.o \ | |||
| $(OBJDIR)/juce_SystemStats_c00d8758.o \ | |||
| $(OBJDIR)/juce_Time_16acdd6f.o \ | |||
| $(OBJDIR)/juce_Uuid_f277575d.o \ | |||
| @@ -719,6 +720,11 @@ $(OBJDIR)/juce_RelativeTime_bc5ef35b.o: ../../src/core/juce_RelativeTime.cpp | |||
| @echo "Compiling juce_RelativeTime.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_Result_d8f437f.o: ../../src/core/juce_Result.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_Result.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_SystemStats_c00d8758.o: ../../src/core/juce_SystemStats.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_SystemStats.cpp" | |||
| @@ -75,6 +75,7 @@ | |||
| 6A53DA58B55E2DE7241BF2C8 = { isa = PBXBuildFile; fileRef = 4555F03DBD059EEDECEF9F85; }; | |||
| 0FF71870483AC46D5B7AC5B0 = { isa = PBXBuildFile; fileRef = DF6CAC67C0F2D379BDA03062; }; | |||
| FA01B3EABA192AE041D4FE4D = { isa = PBXBuildFile; fileRef = CFAECB6551F48A1695DEC243; }; | |||
| 43047D78351C2D7047F4F81E = { isa = PBXBuildFile; fileRef = 0AD73B8EA0D60D9927B36624; }; | |||
| 5BF44F954E56B7C2DD15EAEA = { isa = PBXBuildFile; fileRef = 18B170E96511BBA1019C66F8; }; | |||
| B14EB5F3829CA26DA906D5C0 = { isa = PBXBuildFile; fileRef = 8D2DE1F3CB15D003C90042E7; }; | |||
| D75943C2812EA68CA74D9FDA = { isa = PBXBuildFile; fileRef = CEF91E0C9CBB3EBFF9500FDA; }; | |||
| @@ -539,6 +540,8 @@ | |||
| 8D499CED6DCF525ACD6E39B2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_PlatformUtilities.h; path = ../../src/core/juce_PlatformUtilities.h; sourceTree = SOURCE_ROOT; }; | |||
| CFAECB6551F48A1695DEC243 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RelativeTime.cpp; path = ../../src/core/juce_RelativeTime.cpp; sourceTree = SOURCE_ROOT; }; | |||
| B4137E4612C1D161894D0D27 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_RelativeTime.h; path = ../../src/core/juce_RelativeTime.h; sourceTree = SOURCE_ROOT; }; | |||
| 0AD73B8EA0D60D9927B36624 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Result.cpp; path = ../../src/core/juce_Result.cpp; sourceTree = SOURCE_ROOT; }; | |||
| F51969AF328D2C7D52D7436D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Result.h; path = ../../src/core/juce_Result.h; sourceTree = SOURCE_ROOT; }; | |||
| C25D6136DF9CE441D6EB4C42 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Singleton.h; path = ../../src/core/juce_Singleton.h; sourceTree = SOURCE_ROOT; }; | |||
| CA66415F6EAA172B83755954 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StandardHeader.h; path = ../../src/core/juce_StandardHeader.h; sourceTree = SOURCE_ROOT; }; | |||
| 18B170E96511BBA1019C66F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_SystemStats.cpp; path = ../../src/core/juce_SystemStats.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1303,6 +1306,8 @@ | |||
| 8D499CED6DCF525ACD6E39B2, | |||
| CFAECB6551F48A1695DEC243, | |||
| B4137E4612C1D161894D0D27, | |||
| 0AD73B8EA0D60D9927B36624, | |||
| F51969AF328D2C7D52D7436D, | |||
| C25D6136DF9CE441D6EB4C42, | |||
| CA66415F6EAA172B83755954, | |||
| 18B170E96511BBA1019C66F8, | |||
| @@ -2100,6 +2105,7 @@ | |||
| 6A53DA58B55E2DE7241BF2C8, | |||
| 0FF71870483AC46D5B7AC5B0, | |||
| FA01B3EABA192AE041D4FE4D, | |||
| 43047D78351C2D7047F4F81E, | |||
| 5BF44F954E56B7C2DD15EAEA, | |||
| B14EB5F3829CA26DA906D5C0, | |||
| D75943C2812EA68CA74D9FDA, | |||
| @@ -373,6 +373,8 @@ | |||
| <File RelativePath="..\..\src\core\juce_PlatformUtilities.h"/> | |||
| <File RelativePath="..\..\src\core\juce_RelativeTime.cpp"/> | |||
| <File RelativePath="..\..\src\core\juce_RelativeTime.h"/> | |||
| <File RelativePath="..\..\src\core\juce_Result.cpp"/> | |||
| <File RelativePath="..\..\src\core\juce_Result.h"/> | |||
| <File RelativePath="..\..\src\core\juce_Singleton.h"/> | |||
| <File RelativePath="..\..\src\core\juce_StandardHeader.h"/> | |||
| <File RelativePath="..\..\src\core\juce_SystemStats.cpp"/> | |||
| @@ -373,6 +373,8 @@ | |||
| <File RelativePath="..\..\src\core\juce_PlatformUtilities.h"/> | |||
| <File RelativePath="..\..\src\core\juce_RelativeTime.cpp"/> | |||
| <File RelativePath="..\..\src\core\juce_RelativeTime.h"/> | |||
| <File RelativePath="..\..\src\core\juce_Result.cpp"/> | |||
| <File RelativePath="..\..\src\core\juce_Result.h"/> | |||
| <File RelativePath="..\..\src\core\juce_Singleton.h"/> | |||
| <File RelativePath="..\..\src\core\juce_StandardHeader.h"/> | |||
| <File RelativePath="..\..\src\core\juce_SystemStats.cpp"/> | |||
| @@ -375,6 +375,8 @@ | |||
| <File RelativePath="..\..\src\core\juce_PlatformUtilities.h"/> | |||
| <File RelativePath="..\..\src\core\juce_RelativeTime.cpp"/> | |||
| <File RelativePath="..\..\src\core\juce_RelativeTime.h"/> | |||
| <File RelativePath="..\..\src\core\juce_Result.cpp"/> | |||
| <File RelativePath="..\..\src\core\juce_Result.h"/> | |||
| <File RelativePath="..\..\src\core\juce_Singleton.h"/> | |||
| <File RelativePath="..\..\src\core\juce_StandardHeader.h"/> | |||
| <File RelativePath="..\..\src\core\juce_SystemStats.cpp"/> | |||
| @@ -189,6 +189,7 @@ | |||
| <ClCompile Include="..\..\src\core\juce_Logger.cpp"/> | |||
| <ClCompile Include="..\..\src\core\juce_PerformanceCounter.cpp"/> | |||
| <ClCompile Include="..\..\src\core\juce_RelativeTime.cpp"/> | |||
| <ClCompile Include="..\..\src\core\juce_Result.cpp"/> | |||
| <ClCompile Include="..\..\src\core\juce_SystemStats.cpp"/> | |||
| <ClCompile Include="..\..\src\core\juce_Time.cpp"/> | |||
| <ClCompile Include="..\..\src\core\juce_Uuid.cpp"/> | |||
| @@ -549,6 +550,7 @@ | |||
| <ClInclude Include="..\..\src\core\juce_PlatformDefs.h"/> | |||
| <ClInclude Include="..\..\src\core\juce_PlatformUtilities.h"/> | |||
| <ClInclude Include="..\..\src\core\juce_RelativeTime.h"/> | |||
| <ClInclude Include="..\..\src\core\juce_Result.h"/> | |||
| <ClInclude Include="..\..\src\core\juce_Singleton.h"/> | |||
| <ClInclude Include="..\..\src\core\juce_StandardHeader.h"/> | |||
| <ClInclude Include="..\..\src\core\juce_SystemStats.h"/> | |||
| @@ -424,6 +424,9 @@ | |||
| <ClCompile Include="..\..\src\core\juce_RelativeTime.cpp"> | |||
| <Filter>Juce\Source\core</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\src\core\juce_Result.cpp"> | |||
| <Filter>Juce\Source\core</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\src\core\juce_SystemStats.cpp"> | |||
| <Filter>Juce\Source\core</Filter> | |||
| </ClCompile> | |||
| @@ -1578,6 +1581,9 @@ | |||
| <ClInclude Include="..\..\src\core\juce_RelativeTime.h"> | |||
| <Filter>Juce\Source\core</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\core\juce_Result.h"> | |||
| <Filter>Juce\Source\core</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\core\juce_Singleton.h"> | |||
| <Filter>Juce\Source\core</Filter> | |||
| </ClInclude> | |||
| @@ -75,6 +75,7 @@ | |||
| 6A53DA58B55E2DE7241BF2C8 = { isa = PBXBuildFile; fileRef = 4555F03DBD059EEDECEF9F85; }; | |||
| 0FF71870483AC46D5B7AC5B0 = { isa = PBXBuildFile; fileRef = DF6CAC67C0F2D379BDA03062; }; | |||
| FA01B3EABA192AE041D4FE4D = { isa = PBXBuildFile; fileRef = CFAECB6551F48A1695DEC243; }; | |||
| 43047D78351C2D7047F4F81E = { isa = PBXBuildFile; fileRef = 0AD73B8EA0D60D9927B36624; }; | |||
| 5BF44F954E56B7C2DD15EAEA = { isa = PBXBuildFile; fileRef = 18B170E96511BBA1019C66F8; }; | |||
| B14EB5F3829CA26DA906D5C0 = { isa = PBXBuildFile; fileRef = 8D2DE1F3CB15D003C90042E7; }; | |||
| D75943C2812EA68CA74D9FDA = { isa = PBXBuildFile; fileRef = CEF91E0C9CBB3EBFF9500FDA; }; | |||
| @@ -539,6 +540,8 @@ | |||
| 8D499CED6DCF525ACD6E39B2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_PlatformUtilities.h; path = ../../src/core/juce_PlatformUtilities.h; sourceTree = SOURCE_ROOT; }; | |||
| CFAECB6551F48A1695DEC243 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RelativeTime.cpp; path = ../../src/core/juce_RelativeTime.cpp; sourceTree = SOURCE_ROOT; }; | |||
| B4137E4612C1D161894D0D27 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_RelativeTime.h; path = ../../src/core/juce_RelativeTime.h; sourceTree = SOURCE_ROOT; }; | |||
| 0AD73B8EA0D60D9927B36624 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Result.cpp; path = ../../src/core/juce_Result.cpp; sourceTree = SOURCE_ROOT; }; | |||
| F51969AF328D2C7D52D7436D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Result.h; path = ../../src/core/juce_Result.h; sourceTree = SOURCE_ROOT; }; | |||
| C25D6136DF9CE441D6EB4C42 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Singleton.h; path = ../../src/core/juce_Singleton.h; sourceTree = SOURCE_ROOT; }; | |||
| CA66415F6EAA172B83755954 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StandardHeader.h; path = ../../src/core/juce_StandardHeader.h; sourceTree = SOURCE_ROOT; }; | |||
| 18B170E96511BBA1019C66F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_SystemStats.cpp; path = ../../src/core/juce_SystemStats.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1303,6 +1306,8 @@ | |||
| 8D499CED6DCF525ACD6E39B2, | |||
| CFAECB6551F48A1695DEC243, | |||
| B4137E4612C1D161894D0D27, | |||
| 0AD73B8EA0D60D9927B36624, | |||
| F51969AF328D2C7D52D7436D, | |||
| C25D6136DF9CE441D6EB4C42, | |||
| CA66415F6EAA172B83755954, | |||
| 18B170E96511BBA1019C66F8, | |||
| @@ -2104,6 +2109,7 @@ | |||
| 6A53DA58B55E2DE7241BF2C8, | |||
| 0FF71870483AC46D5B7AC5B0, | |||
| FA01B3EABA192AE041D4FE4D, | |||
| 43047D78351C2D7047F4F81E, | |||
| 5BF44F954E56B7C2DD15EAEA, | |||
| B14EB5F3829CA26DA906D5C0, | |||
| D75943C2812EA68CA74D9FDA, | |||
| @@ -419,6 +419,8 @@ | |||
| file="src/core/juce_RelativeTime.cpp"/> | |||
| <FILE id="51S3JEvsR" name="juce_RelativeTime.h" compile="0" resource="0" | |||
| file="src/core/juce_RelativeTime.h"/> | |||
| <FILE id="OY7VBZ" name="juce_Result.cpp" compile="1" resource="0" file="src/core/juce_Result.cpp"/> | |||
| <FILE id="P3z9OH" name="juce_Result.h" compile="0" resource="0" file="src/core/juce_Result.h"/> | |||
| <FILE id="Xzwb9sOhG" name="juce_Singleton.h" compile="0" resource="0" | |||
| file="src/core/juce_Singleton.h"/> | |||
| <FILE id="bFwbnH0yK" name="juce_StandardHeader.h" compile="0" resource="0" | |||
| @@ -103,6 +103,7 @@ | |||
| #include "../src/maths/juce_Random.cpp" | |||
| #include "../src/core/juce_RelativeTime.cpp" | |||
| #include "../src/core/juce_SystemStats.cpp" | |||
| #include "../src/core/juce_Result.cpp" | |||
| #include "../src/core/juce_Time.cpp" | |||
| #include "../src/core/juce_Initialisation.cpp" | |||
| #include "../src/containers/juce_AbstractFifo.cpp" | |||
| @@ -1687,6 +1687,69 @@ END_JUCE_NAMESPACE | |||
| /*** End of inlined file: juce_SystemStats.cpp ***/ | |||
| /*** Start of inlined file: juce_Result.cpp ***/ | |||
| BEGIN_JUCE_NAMESPACE | |||
| Result::Result (const String& message) noexcept | |||
| : errorMessage (message) | |||
| { | |||
| } | |||
| Result::Result (const Result& other) | |||
| : errorMessage (other.errorMessage) | |||
| { | |||
| } | |||
| Result& Result::operator= (const Result& other) | |||
| { | |||
| errorMessage = other.errorMessage; | |||
| return *this; | |||
| } | |||
| bool Result::operator== (const Result& other) const noexcept | |||
| { | |||
| return errorMessage == other.errorMessage; | |||
| } | |||
| bool Result::operator!= (const Result& other) const noexcept | |||
| { | |||
| return errorMessage != other.errorMessage; | |||
| } | |||
| const Result Result::ok() noexcept | |||
| { | |||
| return Result (String::empty); | |||
| } | |||
| const Result Result::fail (const String& errorMessage) noexcept | |||
| { | |||
| return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); | |||
| } | |||
| bool Result::wasOk() const noexcept | |||
| { | |||
| return errorMessage.isEmpty(); | |||
| } | |||
| bool Result::failed() const noexcept | |||
| { | |||
| return errorMessage.isNotEmpty(); | |||
| } | |||
| Result::operator bool() const noexcept | |||
| { | |||
| return errorMessage.isEmpty(); | |||
| } | |||
| const String Result::getErrorMessage() const noexcept | |||
| { | |||
| return errorMessage; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| /*** End of inlined file: juce_Result.cpp ***/ | |||
| /*** Start of inlined file: juce_Time.cpp ***/ | |||
| #if JUCE_MSVC | |||
| #pragma warning (push) | |||
| @@ -7867,37 +7930,44 @@ const String File::descriptionOfSizeInBytes (const int64 bytes) | |||
| else return String (bytes / (1024.0 * 1024.0 * 1024.0), 1) + " GB"; | |||
| } | |||
| bool File::create() const | |||
| const Result File::create() const | |||
| { | |||
| if (exists()) | |||
| return true; | |||
| return Result::ok(); | |||
| { | |||
| const File parentDir (getParentDirectory()); | |||
| const File parentDir (getParentDirectory()); | |||
| if (parentDir == *this || ! parentDir.createDirectory()) | |||
| return false; | |||
| if (parentDir == *this) | |||
| return Result::fail ("Cannot create parent directory"); | |||
| Result r (parentDir.createDirectory()); | |||
| if (r.wasOk()) | |||
| { | |||
| FileOutputStream fo (*this, 8); | |||
| r = fo.getStatus(); | |||
| } | |||
| return exists(); | |||
| return r; | |||
| } | |||
| bool File::createDirectory() const | |||
| const Result File::createDirectory() const | |||
| { | |||
| if (! isDirectory()) | |||
| { | |||
| const File parentDir (getParentDirectory()); | |||
| if (isDirectory()) | |||
| return Result::ok(); | |||
| if (parentDir == *this || ! parentDir.createDirectory()) | |||
| return false; | |||
| const File parentDir (getParentDirectory()); | |||
| createDirectoryInternal (fullPath.trimCharactersAtEnd (separatorString)); | |||
| return isDirectory(); | |||
| } | |||
| if (parentDir == *this) | |||
| return Result::fail ("Cannot create parent directory"); | |||
| return true; | |||
| Result r (parentDir.createDirectory()); | |||
| if (r.wasOk()) | |||
| r = createDirectoryInternal (fullPath.trimCharactersAtEnd (separatorString)); | |||
| return r; | |||
| } | |||
| const Time File::getLastModificationTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (m); } | |||
| @@ -8464,6 +8534,7 @@ FileInputStream::FileInputStream (const File& f) | |||
| fileHandle (nullptr), | |||
| currentPosition (0), | |||
| totalSize (0), | |||
| status (Result::ok()), | |||
| needToSeek (true) | |||
| { | |||
| openHandle(); | |||
| @@ -8527,6 +8598,7 @@ int64 juce_fileSetPosition (void* handle, int64 pos); | |||
| FileOutputStream::FileOutputStream (const File& f, const int bufferSize_) | |||
| : file (f), | |||
| fileHandle (nullptr), | |||
| status (Result::ok()), | |||
| currentPosition (0), | |||
| bufferSize (bufferSize_), | |||
| bytesInBuffer (0), | |||
| @@ -19644,8 +19716,7 @@ void RecentlyOpenedFilesList::setMaxNumberOfItems (const int newMaxNumber) | |||
| { | |||
| maxNumberOfItems = jmax (1, newMaxNumber); | |||
| while (getNumFiles() > maxNumberOfItems) | |||
| files.remove (getNumFiles() - 1); | |||
| files.removeRange (maxNumberOfItems, getNumFiles()); | |||
| } | |||
| int RecentlyOpenedFilesList::getNumFiles() const | |||
| @@ -19665,10 +19736,8 @@ void RecentlyOpenedFilesList::clear() | |||
| void RecentlyOpenedFilesList::addFile (const File& file) | |||
| { | |||
| const String path (file.getFullPathName()); | |||
| files.removeString (path, true); | |||
| files.insert (0, path); | |||
| removeFile (file); | |||
| files.insert (0, file.getFullPathName()); | |||
| setMaxNumberOfItems (maxNumberOfItems); | |||
| } | |||
| @@ -37110,29 +37179,40 @@ private: | |||
| Entry* findEntry (const uint32 destNodeId, int& insertIndex) const noexcept | |||
| { | |||
| Entry* result = nullptr; | |||
| int firstElement = 0, lastElement = entries.size(); | |||
| while (firstElement < lastElement) | |||
| int start = 0; | |||
| int end = entries.size(); | |||
| for (;;) | |||
| { | |||
| Entry* const firstEntry = entries.getUnchecked (firstElement); | |||
| if (destNodeId == firstEntry->destNodeId) | |||
| if (start >= end) | |||
| { | |||
| result = firstEntry; | |||
| break; | |||
| } | |||
| const int halfway = (firstElement + lastElement) / 2; | |||
| if (halfway <= firstElement) | |||
| else if (destNodeId == entries.getUnchecked (start)->destNodeId) | |||
| { | |||
| result = entries.getUnchecked (start); | |||
| break; | |||
| if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) | |||
| firstElement = halfway; | |||
| } | |||
| else | |||
| lastElement = halfway; | |||
| { | |||
| const int halfway = (start + end) / 2; | |||
| if (halfway == start) | |||
| { | |||
| if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) | |||
| ++start; | |||
| break; | |||
| } | |||
| else if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) | |||
| start = halfway; | |||
| else | |||
| end = halfway; | |||
| } | |||
| } | |||
| insertIndex = firstElement; | |||
| insertIndex = start; | |||
| return result; | |||
| } | |||
| @@ -49857,7 +49937,7 @@ const Image ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | |||
| return snapshot; | |||
| } | |||
| void ListBox::startDragAndDrop (const MouseEvent& e, const var& dragDescription) | |||
| void ListBox::startDragAndDrop (const MouseEvent& e, const var& dragDescription, bool allowDraggingToOtherWindows) | |||
| { | |||
| DragAndDropContainer* const dragContainer | |||
| = DragAndDropContainer::findParentDragContainerFor (this); | |||
| @@ -49869,7 +49949,7 @@ void ListBox::startDragAndDrop (const MouseEvent& e, const var& dragDescription) | |||
| MouseEvent e2 (e.getEventRelativeTo (this)); | |||
| const Point<int> p (x - e2.x, y - e2.y); | |||
| dragContainer->startDragging (dragDescription, this, dragImage, true, &p); | |||
| dragContainer->startDragging (dragDescription, this, dragImage, allowDraggingToOtherWindows, &p); | |||
| } | |||
| else | |||
| { | |||
| @@ -243728,6 +243808,17 @@ namespace WindowsFileHelpers | |||
| return File::nonexistent; | |||
| } | |||
| const Result getResultForLastError() | |||
| { | |||
| TCHAR messageBuffer [256] = { 0 }; | |||
| FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |||
| nullptr, GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), | |||
| messageBuffer, numElementsInArray (messageBuffer) - 1, nullptr); | |||
| return Result::fail (String (messageBuffer)); | |||
| } | |||
| } | |||
| const juce_wchar File::separator = '\\'; | |||
| @@ -243823,9 +243914,10 @@ bool File::moveInternal (const File& dest) const | |||
| return MoveFile (fullPath.toWideCharPointer(), dest.getFullPathName().toWideCharPointer()) != 0; | |||
| } | |||
| void File::createDirectoryInternal (const String& fileName) const | |||
| const Result File::createDirectoryInternal (const String& fileName) const | |||
| { | |||
| CreateDirectory (fileName.toWideCharPointer(), 0); | |||
| return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok() | |||
| : WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| @@ -243845,6 +243937,8 @@ void FileInputStream::openHandle() | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| fileHandle = (void*) h; | |||
| else | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| void FileInputStream::closeHandle() | |||
| @@ -243857,7 +243951,9 @@ size_t FileInputStream::readInternal (void* buffer, size_t numBytes) | |||
| if (fileHandle != 0) | |||
| { | |||
| DWORD actualNum = 0; | |||
| ReadFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| if (! ReadFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0)) | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| return (size_t) actualNum; | |||
| } | |||
| @@ -243879,8 +243975,11 @@ void FileOutputStream::openHandle() | |||
| { | |||
| fileHandle = (void*) h; | |||
| currentPosition = li.QuadPart; | |||
| return; | |||
| } | |||
| } | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| void FileOutputStream::closeHandle() | |||
| @@ -243890,10 +243989,12 @@ void FileOutputStream::closeHandle() | |||
| int FileOutputStream::writeInternal (const void* buffer, int numBytes) | |||
| { | |||
| if (fileHandle != 0) | |||
| if (fileHandle != nullptr) | |||
| { | |||
| DWORD actualNum = 0; | |||
| WriteFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| if (! WriteFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0)) | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| return (int) actualNum; | |||
| } | |||
| @@ -243902,8 +244003,9 @@ int FileOutputStream::writeInternal (const void* buffer, int numBytes) | |||
| void FileOutputStream::flushInternal() | |||
| { | |||
| if (fileHandle != 0) | |||
| FlushFileBuffers ((HANDLE) fileHandle); | |||
| if (fileHandle != nullptr) | |||
| if (! FlushFileBuffers ((HANDLE) fileHandle)) | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| int64 File::getSize() const | |||
| @@ -259463,6 +259565,16 @@ namespace | |||
| if (isReadOnly != nullptr) | |||
| *isReadOnly = access (path.toUTF8(), W_OK) != 0; | |||
| } | |||
| const Result getResultForErrno() | |||
| { | |||
| return Result::fail (String (strerror (errno))); | |||
| } | |||
| const Result getResultForReturnValue (int value) | |||
| { | |||
| return value == -1 ? getResultForErrno() : Result::ok(); | |||
| } | |||
| } | |||
| bool File::isDirectory() const | |||
| @@ -259582,9 +259694,9 @@ bool File::moveInternal (const File& dest) const | |||
| return false; | |||
| } | |||
| void File::createDirectoryInternal (const String& fileName) const | |||
| const Result File::createDirectoryInternal (const String& fileName) const | |||
| { | |||
| mkdir (fileName.toUTF8(), 0777); | |||
| return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| @@ -259603,6 +259715,8 @@ void FileInputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| void FileInputStream::closeHandle() | |||
| @@ -259616,10 +259730,20 @@ void FileInputStream::closeHandle() | |||
| size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes)); | |||
| { | |||
| result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes); | |||
| return 0; | |||
| if (result < 0) | |||
| { | |||
| status = getResultForErrno(); | |||
| result = 0; | |||
| } | |||
| } | |||
| return (size_t) result; | |||
| } | |||
| void FileOutputStream::openHandle() | |||
| @@ -259633,9 +259757,18 @@ void FileOutputStream::openHandle() | |||
| currentPosition = lseek (f, 0, SEEK_END); | |||
| if (currentPosition >= 0) | |||
| { | |||
| fileHandle = (void*) f; | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| close (f); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| else | |||
| @@ -259644,6 +259777,8 @@ void FileOutputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| @@ -259658,16 +259793,24 @@ void FileOutputStream::closeHandle() | |||
| int FileOutputStream::writeInternal (const void* const data, const int numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| { | |||
| result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| return 0; | |||
| if (result == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| return (int) result; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| { | |||
| if (fileHandle != 0) | |||
| fsync ((int) (pointer_sized_int) fileHandle); | |||
| if (fsync ((int) (pointer_sized_int) fileHandle) == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| const File juce_getExecutableFile() | |||
| @@ -269382,6 +269525,16 @@ namespace | |||
| if (isReadOnly != nullptr) | |||
| *isReadOnly = access (path.toUTF8(), W_OK) != 0; | |||
| } | |||
| const Result getResultForErrno() | |||
| { | |||
| return Result::fail (String (strerror (errno))); | |||
| } | |||
| const Result getResultForReturnValue (int value) | |||
| { | |||
| return value == -1 ? getResultForErrno() : Result::ok(); | |||
| } | |||
| } | |||
| bool File::isDirectory() const | |||
| @@ -269501,9 +269654,9 @@ bool File::moveInternal (const File& dest) const | |||
| return false; | |||
| } | |||
| void File::createDirectoryInternal (const String& fileName) const | |||
| const Result File::createDirectoryInternal (const String& fileName) const | |||
| { | |||
| mkdir (fileName.toUTF8(), 0777); | |||
| return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| @@ -269522,6 +269675,8 @@ void FileInputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| void FileInputStream::closeHandle() | |||
| @@ -269535,10 +269690,20 @@ void FileInputStream::closeHandle() | |||
| size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes)); | |||
| { | |||
| result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes); | |||
| return 0; | |||
| if (result < 0) | |||
| { | |||
| status = getResultForErrno(); | |||
| result = 0; | |||
| } | |||
| } | |||
| return (size_t) result; | |||
| } | |||
| void FileOutputStream::openHandle() | |||
| @@ -269552,9 +269717,18 @@ void FileOutputStream::openHandle() | |||
| currentPosition = lseek (f, 0, SEEK_END); | |||
| if (currentPosition >= 0) | |||
| { | |||
| fileHandle = (void*) f; | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| close (f); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| else | |||
| @@ -269563,6 +269737,8 @@ void FileOutputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| @@ -269577,16 +269753,24 @@ void FileOutputStream::closeHandle() | |||
| int FileOutputStream::writeInternal (const void* const data, const int numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| { | |||
| result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| return 0; | |||
| if (result == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| return (int) result; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| { | |||
| if (fileHandle != 0) | |||
| fsync ((int) (pointer_sized_int) fileHandle); | |||
| if (fsync ((int) (pointer_sized_int) fileHandle) == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| const File juce_getExecutableFile() | |||
| @@ -285777,6 +285961,16 @@ namespace | |||
| if (isReadOnly != nullptr) | |||
| *isReadOnly = access (path.toUTF8(), W_OK) != 0; | |||
| } | |||
| const Result getResultForErrno() | |||
| { | |||
| return Result::fail (String (strerror (errno))); | |||
| } | |||
| const Result getResultForReturnValue (int value) | |||
| { | |||
| return value == -1 ? getResultForErrno() : Result::ok(); | |||
| } | |||
| } | |||
| bool File::isDirectory() const | |||
| @@ -285896,9 +286090,9 @@ bool File::moveInternal (const File& dest) const | |||
| return false; | |||
| } | |||
| void File::createDirectoryInternal (const String& fileName) const | |||
| const Result File::createDirectoryInternal (const String& fileName) const | |||
| { | |||
| mkdir (fileName.toUTF8(), 0777); | |||
| return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); | |||
| } | |||
| int64 juce_fileSetPosition (void* handle, int64 pos) | |||
| @@ -285917,6 +286111,8 @@ void FileInputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| void FileInputStream::closeHandle() | |||
| @@ -285930,10 +286126,20 @@ void FileInputStream::closeHandle() | |||
| size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes)); | |||
| { | |||
| result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes); | |||
| return 0; | |||
| if (result < 0) | |||
| { | |||
| status = getResultForErrno(); | |||
| result = 0; | |||
| } | |||
| } | |||
| return (size_t) result; | |||
| } | |||
| void FileOutputStream::openHandle() | |||
| @@ -285947,9 +286153,18 @@ void FileOutputStream::openHandle() | |||
| currentPosition = lseek (f, 0, SEEK_END); | |||
| if (currentPosition >= 0) | |||
| { | |||
| fileHandle = (void*) f; | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| close (f); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| else | |||
| @@ -285958,6 +286173,8 @@ void FileOutputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| @@ -285972,16 +286189,24 @@ void FileOutputStream::closeHandle() | |||
| int FileOutputStream::writeInternal (const void* const data, const int numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| { | |||
| result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| return 0; | |||
| if (result == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| return (int) result; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| { | |||
| if (fileHandle != 0) | |||
| fsync ((int) (pointer_sized_int) fileHandle); | |||
| if (fsync ((int) (pointer_sized_int) fileHandle) == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| const File juce_getExecutableFile() | |||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 53 | |||
| #define JUCE_BUILDNUMBER 75 | |||
| #define JUCE_BUILDNUMBER 76 | |||
| /** Current Juce version number. | |||
| @@ -11998,6 +11998,85 @@ JUCE_API bool operator>= (const Time& time1, const Time& time2); | |||
| #endif // __JUCE_TIME_JUCEHEADER__ | |||
| /*** End of inlined file: juce_Time.h ***/ | |||
| /*** Start of inlined file: juce_Result.h ***/ | |||
| #ifndef __JUCE_RESULT_JUCEHEADER__ | |||
| #define __JUCE_RESULT_JUCEHEADER__ | |||
| /** | |||
| Represents the 'success' or 'failure' of an operation, and holds an associated | |||
| error message to describe the error when there's a failure. | |||
| E.g. | |||
| @code | |||
| const Result myOperation() | |||
| { | |||
| if (doSomeKindOfFoobar()) | |||
| return Result::ok(); | |||
| else | |||
| return Result::fail ("foobar didn't work!"); | |||
| } | |||
| const Result result (myOperation()); | |||
| if (result.wasOk()) | |||
| { | |||
| ...it's all good... | |||
| } | |||
| else | |||
| { | |||
| warnUserAboutFailure ("The foobar operation failed! Error message was: " | |||
| + result.getErrorMessage()); | |||
| } | |||
| @endcode | |||
| */ | |||
| class Result | |||
| { | |||
| public: | |||
| /** Creates and returns a 'successful' result. */ | |||
| static const Result ok() noexcept; | |||
| /** Creates a 'failure' result. | |||
| If you pass a blank error message in here, a default "Unknown Error" message | |||
| will be used instead. | |||
| */ | |||
| static const Result fail (const String& errorMessage) noexcept; | |||
| /** Returns true if this result indicates a success. */ | |||
| bool wasOk() const noexcept; | |||
| /** Returns true if this result indicates a failure. | |||
| You can use getErrorMessage() to retrieve the error message associated | |||
| with the failure. | |||
| */ | |||
| bool failed() const noexcept; | |||
| /** Returns true if this result indicates a success. | |||
| This is equivalent to calling wasOk(). | |||
| */ | |||
| operator bool() const noexcept; | |||
| /** Returns the error message that was set when this result was created. | |||
| For a successful result, this will be an empty string; | |||
| */ | |||
| const String getErrorMessage() const noexcept; | |||
| Result (const Result& other); | |||
| Result& operator= (const Result& other); | |||
| bool operator== (const Result& other) const noexcept; | |||
| bool operator!= (const Result& other) const noexcept; | |||
| private: | |||
| String errorMessage; | |||
| explicit Result (const String& errorMessage) noexcept; | |||
| }; | |||
| #endif // __JUCE_RESULT_JUCEHEADER__ | |||
| /*** End of inlined file: juce_Result.h ***/ | |||
| class FileInputStream; | |||
| class FileOutputStream; | |||
| @@ -12378,18 +12457,18 @@ public: | |||
| @returns true if the file has been created (or if it already existed). | |||
| @see createDirectory | |||
| */ | |||
| bool create() const; | |||
| const Result create() const; | |||
| /** Creates a new directory for this filename. | |||
| This will try to create the file as a directory, and fill also create | |||
| any parent directories it needs in order to complete the operation. | |||
| @returns true if the directory has been created successfully, (or if it | |||
| already existed beforehand). | |||
| @returns a result to indicate whether the directory was created successfully, or | |||
| an error message if it failed. | |||
| @see create | |||
| */ | |||
| bool createDirectory() const; | |||
| const Result createDirectory() const; | |||
| /** Deletes a file. | |||
| @@ -12869,7 +12948,7 @@ private: | |||
| File (const String&, int); | |||
| const String getPathUpToLastSlash() const; | |||
| void createDirectoryInternal (const String& fileName) const; | |||
| const Result createDirectoryInternal (const String& fileName) const; | |||
| bool copyInternal (const File& dest) const; | |||
| bool moveInternal (const File& dest) const; | |||
| bool setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const; | |||
| @@ -17832,6 +17911,9 @@ private: | |||
| #endif | |||
| #ifndef __JUCE_RELATIVETIME_JUCEHEADER__ | |||
| #endif | |||
| #ifndef __JUCE_RESULT_JUCEHEADER__ | |||
| #endif | |||
| #ifndef __JUCE_SINGLETON_JUCEHEADER__ | |||
| @@ -19086,7 +19168,14 @@ public: | |||
| /** Destructor. */ | |||
| ~FileInputStream(); | |||
| const File& getFile() const noexcept { return file; } | |||
| /** Returns the file that this stream is reading from. */ | |||
| const File& getFile() const noexcept { return file; } | |||
| /** Returns the status of the file stream. | |||
| The result will be ok if the file opened successfully. If an error occurs while | |||
| opening or reading from the file, this will contain an error message. | |||
| */ | |||
| const Result getStatus() const { return status; } | |||
| int64 getTotalLength(); | |||
| int read (void* destBuffer, int maxBytesToRead); | |||
| @@ -19099,6 +19188,7 @@ private: | |||
| File file; | |||
| void* fileHandle; | |||
| int64 currentPosition, totalSize; | |||
| Result status; | |||
| bool needToSeek; | |||
| void openHandle(); | |||
| @@ -19154,9 +19244,16 @@ public: | |||
| */ | |||
| const File& getFile() const { return file; } | |||
| /** Returns the status of the file stream. | |||
| The result will be ok if the file opened successfully. If an error occurs while | |||
| opening or writing to the file, this will contain an error message. | |||
| */ | |||
| const Result getStatus() const { return status; } | |||
| /** Returns true if the stream couldn't be opened for some reason. | |||
| @see getResult() | |||
| */ | |||
| bool failedToOpen() const { return fileHandle == 0; } | |||
| bool failedToOpen() const { return status.failed(); } | |||
| void flush(); | |||
| int64 getPosition(); | |||
| @@ -19167,6 +19264,7 @@ private: | |||
| File file; | |||
| void* fileHandle; | |||
| Result status; | |||
| int64 currentPosition; | |||
| int bufferSize, bytesInBuffer; | |||
| HeapBlock <char> buffer; | |||
| @@ -22219,6 +22317,13 @@ public: | |||
| If signal() is called when nothing is waiting, the next thread to call wait() | |||
| will return immediately and reset the signal. | |||
| If the WaitableEvent is manual reset, all threads that are currently waiting on this | |||
| object will be woken. | |||
| If the WaitableEvent is automatic reset, and there are one or more threads waiting | |||
| on the object, then one of them will be woken up. If no threads are currently waiting, | |||
| then the next thread to call wait() will be woken up. | |||
| @see wait, reset | |||
| */ | |||
| void signal() const noexcept; | |||
| @@ -46884,7 +46989,7 @@ public: | |||
| /** @internal */ | |||
| void colourChanged(); | |||
| /** @internal */ | |||
| void startDragAndDrop (const MouseEvent& e, const var& dragDescription); | |||
| void startDragAndDrop (const MouseEvent& e, const var& dragDescription, bool allowDraggingToOtherWindows = true); | |||
| private: | |||
| @@ -703,29 +703,40 @@ private: | |||
| Entry* findEntry (const uint32 destNodeId, int& insertIndex) const noexcept | |||
| { | |||
| Entry* result = nullptr; | |||
| int firstElement = 0, lastElement = entries.size(); | |||
| while (firstElement < lastElement) | |||
| int start = 0; | |||
| int end = entries.size(); | |||
| for (;;) | |||
| { | |||
| Entry* const firstEntry = entries.getUnchecked (firstElement); | |||
| if (destNodeId == firstEntry->destNodeId) | |||
| if (start >= end) | |||
| { | |||
| result = firstEntry; | |||
| break; | |||
| } | |||
| const int halfway = (firstElement + lastElement) / 2; | |||
| if (halfway <= firstElement) | |||
| else if (destNodeId == entries.getUnchecked (start)->destNodeId) | |||
| { | |||
| result = entries.getUnchecked (start); | |||
| break; | |||
| if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) | |||
| firstElement = halfway; | |||
| } | |||
| else | |||
| lastElement = halfway; | |||
| { | |||
| const int halfway = (start + end) / 2; | |||
| if (halfway == start) | |||
| { | |||
| if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) | |||
| ++start; | |||
| break; | |||
| } | |||
| else if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) | |||
| start = halfway; | |||
| else | |||
| end = halfway; | |||
| } | |||
| } | |||
| insertIndex = firstElement; | |||
| insertIndex = start; | |||
| return result; | |||
| } | |||
| @@ -0,0 +1,92 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "juce_StandardHeader.h" | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "juce_Result.h" | |||
| //============================================================================== | |||
| Result::Result (const String& message) noexcept | |||
| : errorMessage (message) | |||
| { | |||
| } | |||
| Result::Result (const Result& other) | |||
| : errorMessage (other.errorMessage) | |||
| { | |||
| } | |||
| Result& Result::operator= (const Result& other) | |||
| { | |||
| errorMessage = other.errorMessage; | |||
| return *this; | |||
| } | |||
| bool Result::operator== (const Result& other) const noexcept | |||
| { | |||
| return errorMessage == other.errorMessage; | |||
| } | |||
| bool Result::operator!= (const Result& other) const noexcept | |||
| { | |||
| return errorMessage != other.errorMessage; | |||
| } | |||
| const Result Result::ok() noexcept | |||
| { | |||
| return Result (String::empty); | |||
| } | |||
| const Result Result::fail (const String& errorMessage) noexcept | |||
| { | |||
| return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); | |||
| } | |||
| //============================================================================== | |||
| bool Result::wasOk() const noexcept | |||
| { | |||
| return errorMessage.isEmpty(); | |||
| } | |||
| bool Result::failed() const noexcept | |||
| { | |||
| return errorMessage.isNotEmpty(); | |||
| } | |||
| Result::operator bool() const noexcept | |||
| { | |||
| return errorMessage.isEmpty(); | |||
| } | |||
| const String Result::getErrorMessage() const noexcept | |||
| { | |||
| return errorMessage; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -0,0 +1,107 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #ifndef __JUCE_RESULT_JUCEHEADER__ | |||
| #define __JUCE_RESULT_JUCEHEADER__ | |||
| #include "../text/juce_String.h" | |||
| //============================================================================== | |||
| /** | |||
| Represents the 'success' or 'failure' of an operation, and holds an associated | |||
| error message to describe the error when there's a failure. | |||
| E.g. | |||
| @code | |||
| const Result myOperation() | |||
| { | |||
| if (doSomeKindOfFoobar()) | |||
| return Result::ok(); | |||
| else | |||
| return Result::fail ("foobar didn't work!"); | |||
| } | |||
| const Result result (myOperation()); | |||
| if (result.wasOk()) | |||
| { | |||
| ...it's all good... | |||
| } | |||
| else | |||
| { | |||
| warnUserAboutFailure ("The foobar operation failed! Error message was: " | |||
| + result.getErrorMessage()); | |||
| } | |||
| @endcode | |||
| */ | |||
| class Result | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates and returns a 'successful' result. */ | |||
| static const Result ok() noexcept; | |||
| /** Creates a 'failure' result. | |||
| If you pass a blank error message in here, a default "Unknown Error" message | |||
| will be used instead. | |||
| */ | |||
| static const Result fail (const String& errorMessage) noexcept; | |||
| //============================================================================== | |||
| /** Returns true if this result indicates a success. */ | |||
| bool wasOk() const noexcept; | |||
| /** Returns true if this result indicates a failure. | |||
| You can use getErrorMessage() to retrieve the error message associated | |||
| with the failure. | |||
| */ | |||
| bool failed() const noexcept; | |||
| /** Returns true if this result indicates a success. | |||
| This is equivalent to calling wasOk(). | |||
| */ | |||
| operator bool() const noexcept; | |||
| /** Returns the error message that was set when this result was created. | |||
| For a successful result, this will be an empty string; | |||
| */ | |||
| const String getErrorMessage() const noexcept; | |||
| //============================================================================== | |||
| Result (const Result& other); | |||
| Result& operator= (const Result& other); | |||
| bool operator== (const Result& other) const noexcept; | |||
| bool operator!= (const Result& other) const noexcept; | |||
| private: | |||
| String errorMessage; | |||
| explicit Result (const String& errorMessage) noexcept; | |||
| }; | |||
| #endif // __JUCE_RESULT_JUCEHEADER__ | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 53 | |||
| #define JUCE_BUILDNUMBER 75 | |||
| #define JUCE_BUILDNUMBER 76 | |||
| /** Current Juce version number. | |||
| @@ -915,7 +915,7 @@ const Image ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | |||
| return snapshot; | |||
| } | |||
| void ListBox::startDragAndDrop (const MouseEvent& e, const var& dragDescription) | |||
| void ListBox::startDragAndDrop (const MouseEvent& e, const var& dragDescription, bool allowDraggingToOtherWindows) | |||
| { | |||
| DragAndDropContainer* const dragContainer | |||
| = DragAndDropContainer::findParentDragContainerFor (this); | |||
| @@ -927,7 +927,7 @@ void ListBox::startDragAndDrop (const MouseEvent& e, const var& dragDescription) | |||
| MouseEvent e2 (e.getEventRelativeTo (this)); | |||
| const Point<int> p (x - e2.x, y - e2.y); | |||
| dragContainer->startDragging (dragDescription, this, dragImage, true, &p); | |||
| dragContainer->startDragging (dragDescription, this, dragImage, allowDraggingToOtherWindows, &p); | |||
| } | |||
| else | |||
| { | |||
| @@ -560,7 +560,7 @@ public: | |||
| /** @internal */ | |||
| void colourChanged(); | |||
| /** @internal */ | |||
| void startDragAndDrop (const MouseEvent& e, const var& dragDescription); | |||
| void startDragAndDrop (const MouseEvent& e, const var& dragDescription, bool allowDraggingToOtherWindows = true); | |||
| private: | |||
| //============================================================================== | |||
| @@ -445,37 +445,44 @@ const String File::descriptionOfSizeInBytes (const int64 bytes) | |||
| } | |||
| //============================================================================== | |||
| bool File::create() const | |||
| const Result File::create() const | |||
| { | |||
| if (exists()) | |||
| return true; | |||
| return Result::ok(); | |||
| { | |||
| const File parentDir (getParentDirectory()); | |||
| const File parentDir (getParentDirectory()); | |||
| if (parentDir == *this || ! parentDir.createDirectory()) | |||
| return false; | |||
| if (parentDir == *this) | |||
| return Result::fail ("Cannot create parent directory"); | |||
| Result r (parentDir.createDirectory()); | |||
| if (r.wasOk()) | |||
| { | |||
| FileOutputStream fo (*this, 8); | |||
| r = fo.getStatus(); | |||
| } | |||
| return exists(); | |||
| return r; | |||
| } | |||
| bool File::createDirectory() const | |||
| const Result File::createDirectory() const | |||
| { | |||
| if (! isDirectory()) | |||
| { | |||
| const File parentDir (getParentDirectory()); | |||
| if (isDirectory()) | |||
| return Result::ok(); | |||
| if (parentDir == *this || ! parentDir.createDirectory()) | |||
| return false; | |||
| const File parentDir (getParentDirectory()); | |||
| createDirectoryInternal (fullPath.trimCharactersAtEnd (separatorString)); | |||
| return isDirectory(); | |||
| } | |||
| if (parentDir == *this) | |||
| return Result::fail ("Cannot create parent directory"); | |||
| return true; | |||
| Result r (parentDir.createDirectory()); | |||
| if (r.wasOk()) | |||
| r = createDirectoryInternal (fullPath.trimCharactersAtEnd (separatorString)); | |||
| return r; | |||
| } | |||
| //============================================================================== | |||
| @@ -31,6 +31,7 @@ | |||
| #include "../../text/juce_StringArray.h" | |||
| #include "../../memory/juce_MemoryBlock.h" | |||
| #include "../../memory/juce_ScopedPointer.h" | |||
| #include "../../core/juce_Result.h" | |||
| class FileInputStream; | |||
| class FileOutputStream; | |||
| @@ -425,18 +426,18 @@ public: | |||
| @returns true if the file has been created (or if it already existed). | |||
| @see createDirectory | |||
| */ | |||
| bool create() const; | |||
| const Result create() const; | |||
| /** Creates a new directory for this filename. | |||
| This will try to create the file as a directory, and fill also create | |||
| any parent directories it needs in order to complete the operation. | |||
| @returns true if the directory has been created successfully, (or if it | |||
| already existed beforehand). | |||
| @returns a result to indicate whether the directory was created successfully, or | |||
| an error message if it failed. | |||
| @see create | |||
| */ | |||
| bool createDirectory() const; | |||
| const Result createDirectory() const; | |||
| /** Deletes a file. | |||
| @@ -928,7 +929,7 @@ private: | |||
| File (const String&, int); | |||
| const String getPathUpToLastSlash() const; | |||
| void createDirectoryInternal (const String& fileName) const; | |||
| const Result createDirectoryInternal (const String& fileName) const; | |||
| bool copyInternal (const File& dest) const; | |||
| bool moveInternal (const File& dest) const; | |||
| bool setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const; | |||
| @@ -40,6 +40,7 @@ FileInputStream::FileInputStream (const File& f) | |||
| fileHandle (nullptr), | |||
| currentPosition (0), | |||
| totalSize (0), | |||
| status (Result::ok()), | |||
| needToSeek (true) | |||
| { | |||
| openHandle(); | |||
| @@ -51,7 +51,14 @@ public: | |||
| ~FileInputStream(); | |||
| //============================================================================== | |||
| const File& getFile() const noexcept { return file; } | |||
| /** Returns the file that this stream is reading from. */ | |||
| const File& getFile() const noexcept { return file; } | |||
| /** Returns the status of the file stream. | |||
| The result will be ok if the file opened successfully. If an error occurs while | |||
| opening or reading from the file, this will contain an error message. | |||
| */ | |||
| const Result getStatus() const { return status; } | |||
| //============================================================================== | |||
| int64 getTotalLength(); | |||
| @@ -66,6 +73,7 @@ private: | |||
| File file; | |||
| void* fileHandle; | |||
| int64 currentPosition, totalSize; | |||
| Result status; | |||
| bool needToSeek; | |||
| void openHandle(); | |||
| @@ -36,6 +36,7 @@ int64 juce_fileSetPosition (void* handle, int64 pos); | |||
| FileOutputStream::FileOutputStream (const File& f, const int bufferSize_) | |||
| : file (f), | |||
| fileHandle (nullptr), | |||
| status (Result::ok()), | |||
| currentPosition (0), | |||
| bufferSize (bufferSize_), | |||
| bytesInBuffer (0), | |||
| @@ -67,9 +67,16 @@ public: | |||
| */ | |||
| const File& getFile() const { return file; } | |||
| /** Returns the status of the file stream. | |||
| The result will be ok if the file opened successfully. If an error occurs while | |||
| opening or writing to the file, this will contain an error message. | |||
| */ | |||
| const Result getStatus() const { return status; } | |||
| /** Returns true if the stream couldn't be opened for some reason. | |||
| @see getResult() | |||
| */ | |||
| bool failedToOpen() const { return fileHandle == 0; } | |||
| bool failedToOpen() const { return status.failed(); } | |||
| //============================================================================== | |||
| void flush(); | |||
| @@ -82,6 +89,7 @@ private: | |||
| //============================================================================== | |||
| File file; | |||
| void* fileHandle; | |||
| Result status; | |||
| int64 currentPosition; | |||
| int bufferSize, bytesInBuffer; | |||
| HeapBlock <char> buffer; | |||
| @@ -98,6 +98,9 @@ | |||
| #ifndef __JUCE_RELATIVETIME_JUCEHEADER__ | |||
| #include "core/juce_RelativeTime.h" | |||
| #endif | |||
| #ifndef __JUCE_RESULT_JUCEHEADER__ | |||
| #include "core/juce_Result.h" | |||
| #endif | |||
| #ifndef __JUCE_SINGLETON_JUCEHEADER__ | |||
| #include "core/juce_Singleton.h" | |||
| #endif | |||
| @@ -272,6 +272,16 @@ namespace | |||
| if (isReadOnly != nullptr) | |||
| *isReadOnly = access (path.toUTF8(), W_OK) != 0; | |||
| } | |||
| const Result getResultForErrno() | |||
| { | |||
| return Result::fail (String (strerror (errno))); | |||
| } | |||
| const Result getResultForReturnValue (int value) | |||
| { | |||
| return value == -1 ? getResultForErrno() : Result::ok(); | |||
| } | |||
| } | |||
| bool File::isDirectory() const | |||
| @@ -392,9 +402,9 @@ bool File::moveInternal (const File& dest) const | |||
| return false; | |||
| } | |||
| void File::createDirectoryInternal (const String& fileName) const | |||
| const Result File::createDirectoryInternal (const String& fileName) const | |||
| { | |||
| mkdir (fileName.toUTF8(), 0777); | |||
| return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); | |||
| } | |||
| //============================================================================== | |||
| @@ -414,6 +424,8 @@ void FileInputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| void FileInputStream::closeHandle() | |||
| @@ -427,10 +439,20 @@ void FileInputStream::closeHandle() | |||
| size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes)); | |||
| { | |||
| result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes); | |||
| return 0; | |||
| if (result < 0) | |||
| { | |||
| status = getResultForErrno(); | |||
| result = 0; | |||
| } | |||
| } | |||
| return (size_t) result; | |||
| } | |||
| //============================================================================== | |||
| @@ -445,9 +467,18 @@ void FileOutputStream::openHandle() | |||
| currentPosition = lseek (f, 0, SEEK_END); | |||
| if (currentPosition >= 0) | |||
| { | |||
| fileHandle = (void*) f; | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| close (f); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| else | |||
| @@ -456,6 +487,8 @@ void FileOutputStream::openHandle() | |||
| if (f != -1) | |||
| fileHandle = (void*) f; | |||
| else | |||
| status = getResultForErrno(); | |||
| } | |||
| } | |||
| @@ -470,16 +503,24 @@ void FileOutputStream::closeHandle() | |||
| int FileOutputStream::writeInternal (const void* const data, const int numBytes) | |||
| { | |||
| ssize_t result = 0; | |||
| if (fileHandle != 0) | |||
| return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| { | |||
| result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes); | |||
| return 0; | |||
| if (result == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| return (int) result; | |||
| } | |||
| void FileOutputStream::flushInternal() | |||
| { | |||
| if (fileHandle != 0) | |||
| fsync ((int) (pointer_sized_int) fileHandle); | |||
| if (fsync ((int) (pointer_sized_int) fileHandle) == -1) | |||
| status = getResultForErrno(); | |||
| } | |||
| //============================================================================== | |||
| @@ -93,6 +93,17 @@ namespace WindowsFileHelpers | |||
| return File::nonexistent; | |||
| } | |||
| const Result getResultForLastError() | |||
| { | |||
| TCHAR messageBuffer [256] = { 0 }; | |||
| FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |||
| nullptr, GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), | |||
| messageBuffer, numElementsInArray (messageBuffer) - 1, nullptr); | |||
| return Result::fail (String (messageBuffer)); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| @@ -192,9 +203,10 @@ bool File::moveInternal (const File& dest) const | |||
| return MoveFile (fullPath.toWideCharPointer(), dest.getFullPathName().toWideCharPointer()) != 0; | |||
| } | |||
| void File::createDirectoryInternal (const String& fileName) const | |||
| const Result File::createDirectoryInternal (const String& fileName) const | |||
| { | |||
| CreateDirectory (fileName.toWideCharPointer(), 0); | |||
| return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok() | |||
| : WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| //============================================================================== | |||
| @@ -215,6 +227,8 @@ void FileInputStream::openHandle() | |||
| if (h != INVALID_HANDLE_VALUE) | |||
| fileHandle = (void*) h; | |||
| else | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| void FileInputStream::closeHandle() | |||
| @@ -227,7 +241,9 @@ size_t FileInputStream::readInternal (void* buffer, size_t numBytes) | |||
| if (fileHandle != 0) | |||
| { | |||
| DWORD actualNum = 0; | |||
| ReadFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| if (! ReadFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0)) | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| return (size_t) actualNum; | |||
| } | |||
| @@ -250,8 +266,11 @@ void FileOutputStream::openHandle() | |||
| { | |||
| fileHandle = (void*) h; | |||
| currentPosition = li.QuadPart; | |||
| return; | |||
| } | |||
| } | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| void FileOutputStream::closeHandle() | |||
| @@ -261,10 +280,12 @@ void FileOutputStream::closeHandle() | |||
| int FileOutputStream::writeInternal (const void* buffer, int numBytes) | |||
| { | |||
| if (fileHandle != 0) | |||
| if (fileHandle != nullptr) | |||
| { | |||
| DWORD actualNum = 0; | |||
| WriteFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0); | |||
| if (! WriteFile ((HANDLE) fileHandle, buffer, numBytes, &actualNum, 0)) | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| return (int) actualNum; | |||
| } | |||
| @@ -273,8 +294,9 @@ int FileOutputStream::writeInternal (const void* buffer, int numBytes) | |||
| void FileOutputStream::flushInternal() | |||
| { | |||
| if (fileHandle != 0) | |||
| FlushFileBuffers ((HANDLE) fileHandle); | |||
| if (fileHandle != nullptr) | |||
| if (! FlushFileBuffers ((HANDLE) fileHandle)) | |||
| status = WindowsFileHelpers::getResultForLastError(); | |||
| } | |||
| //============================================================================== | |||
| @@ -79,6 +79,13 @@ public: | |||
| If signal() is called when nothing is waiting, the next thread to call wait() | |||
| will return immediately and reset the signal. | |||
| If the WaitableEvent is manual reset, all threads that are currently waiting on this | |||
| object will be woken. | |||
| If the WaitableEvent is automatic reset, and there are one or more threads waiting | |||
| on the object, then one of them will be woken up. If no threads are currently waiting, | |||
| then the next thread to call wait() will be woken up. | |||
| @see wait, reset | |||
| */ | |||
| void signal() const noexcept; | |||
| @@ -45,8 +45,7 @@ void RecentlyOpenedFilesList::setMaxNumberOfItems (const int newMaxNumber) | |||
| { | |||
| maxNumberOfItems = jmax (1, newMaxNumber); | |||
| while (getNumFiles() > maxNumberOfItems) | |||
| files.remove (getNumFiles() - 1); | |||
| files.removeRange (maxNumberOfItems, getNumFiles()); | |||
| } | |||
| int RecentlyOpenedFilesList::getNumFiles() const | |||
| @@ -66,10 +65,8 @@ void RecentlyOpenedFilesList::clear() | |||
| void RecentlyOpenedFilesList::addFile (const File& file) | |||
| { | |||
| const String path (file.getFullPathName()); | |||
| files.removeString (path, true); | |||
| files.insert (0, path); | |||
| removeFile (file); | |||
| files.insert (0, file.getFullPathName()); | |||
| setMaxNumberOfItems (maxNumberOfItems); | |||
| } | |||