1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

New class: Result, for returning error messages from operations. Used this class to report file errors in FileInputStream and FileOutputStream.

This commit is contained in:
Julian Storer 2011-04-16 17:08:53 +01:00
parent e9bdd1d637
commit 6f0740d466
29 changed files with 821 additions and 150 deletions

View file

@ -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"

View file

@ -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,

View file

@ -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"/>

View file

@ -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"/>

View file

@ -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"/>

View file

@ -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"/>

View file

@ -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>

View file

@ -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,

View file

@ -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"

View file

@ -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"

View file

@ -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());
if (parentDir == *this)
return Result::fail ("Cannot create parent directory");
Result r (parentDir.createDirectory());
if (r.wasOk())
{
const File parentDir (getParentDirectory());
if (parentDir == *this || ! parentDir.createDirectory())
return false;
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)
{
if (fileHandle != 0)
return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes));
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes);
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)
{
if (fileHandle != 0)
return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
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)
{
if (fileHandle != 0)
return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes));
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes);
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)
{
if (fileHandle != 0)
return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
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)
{
if (fileHandle != 0)
return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes));
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes);
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)
{
if (fileHandle != 0)
return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
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()

View file

@ -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 true if the stream couldn't be opened for some reason.
/** 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.
*/
bool failedToOpen() const { return fileHandle == 0; }
const Result getStatus() const { return status; }
/** Returns true if the stream couldn't be opened for some reason.
@see getResult()
*/
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:

View file

@ -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;
}

92
src/core/juce_Result.cpp Normal file
View file

@ -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

107
src/core/juce_Result.h Normal file
View file

@ -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__

View file

@ -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.

View file

@ -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
{

View file

@ -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:
//==============================================================================

View file

@ -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());
if (parentDir == *this)
return Result::fail ("Cannot create parent directory");
Result r (parentDir.createDirectory());
if (r.wasOk())
{
const File parentDir (getParentDirectory());
if (parentDir == *this || ! parentDir.createDirectory())
return false;
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;
}
//==============================================================================

View file

@ -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;

View file

@ -40,6 +40,7 @@ FileInputStream::FileInputStream (const File& f)
fileHandle (nullptr),
currentPosition (0),
totalSize (0),
status (Result::ok()),
needToSeek (true)
{
openHandle();

View file

@ -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();

View file

@ -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),

View file

@ -67,9 +67,16 @@ public:
*/
const File& getFile() const { return file; }
/** Returns true if the stream couldn't be opened for some reason.
/** 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.
*/
bool failedToOpen() const { return fileHandle == 0; }
const Result getStatus() const { return status; }
/** Returns true if the stream couldn't be opened for some reason.
@see getResult()
*/
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;

View file

@ -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

View file

@ -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)
{
if (fileHandle != 0)
return jmax ((ssize_t) 0, ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes));
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::read ((int) (pointer_sized_int) fileHandle, buffer, numBytes);
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)
{
if (fileHandle != 0)
return (int) ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
ssize_t result = 0;
return 0;
if (fileHandle != 0)
{
result = ::write ((int) (pointer_sized_int) fileHandle, data, numBytes);
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();
}
//==============================================================================

View file

@ -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();
}
//==============================================================================

View file

@ -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;

View file

@ -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);
}