| @@ -659,6 +659,8 @@ | |||||
| 84B2053F10D535EC008B4A79 /* juce_ValueTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 843D4A3910D3C54500624BA6 /* juce_ValueTree.cpp */; }; | 84B2053F10D535EC008B4A79 /* juce_ValueTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 843D4A3910D3C54500624BA6 /* juce_ValueTree.cpp */; }; | ||||
| 84BA604010F2017A001D9D70 /* juce_Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84BA603E10F2017A001D9D70 /* juce_Value.cpp */; }; | 84BA604010F2017A001D9D70 /* juce_Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84BA603E10F2017A001D9D70 /* juce_Value.cpp */; }; | ||||
| 84BA604110F2017A001D9D70 /* juce_Value.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BA603F10F2017A001D9D70 /* juce_Value.h */; }; | 84BA604110F2017A001D9D70 /* juce_Value.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BA603F10F2017A001D9D70 /* juce_Value.h */; }; | ||||
| 84CABF691101292D0088D64D /* juce_TemporaryFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84CABF671101292D0088D64D /* juce_TemporaryFile.cpp */; }; | |||||
| 84CABF6A1101292D0088D64D /* juce_TemporaryFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 84CABF681101292D0088D64D /* juce_TemporaryFile.h */; }; | |||||
| 84D0F00C109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */; }; | 84D0F00C109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */; }; | ||||
| 84DEDD9F10EE496500909D01 /* juce_HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */; }; | 84DEDD9F10EE496500909D01 /* juce_HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */; }; | ||||
| 84F1E6E710403605006A1807 /* juce_Application.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6DC10403605006A1807 /* juce_Application.cpp */; }; | 84F1E6E710403605006A1807 /* juce_Application.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6DC10403605006A1807 /* juce_Application.cpp */; }; | ||||
| @@ -1270,6 +1272,8 @@ | |||||
| 84AF3FE710EF9FF30035D74F /* juce_ScopedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_ScopedPointer.h; sourceTree = "<group>"; }; | 84AF3FE710EF9FF30035D74F /* juce_ScopedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_ScopedPointer.h; sourceTree = "<group>"; }; | ||||
| 84BA603E10F2017A001D9D70 /* juce_Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_Value.cpp; sourceTree = "<group>"; }; | 84BA603E10F2017A001D9D70 /* juce_Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_Value.cpp; sourceTree = "<group>"; }; | ||||
| 84BA603F10F2017A001D9D70 /* juce_Value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_Value.h; sourceTree = "<group>"; }; | 84BA603F10F2017A001D9D70 /* juce_Value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_Value.h; sourceTree = "<group>"; }; | ||||
| 84CABF671101292D0088D64D /* juce_TemporaryFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_TemporaryFile.cpp; sourceTree = "<group>"; }; | |||||
| 84CABF681101292D0088D64D /* juce_TemporaryFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_TemporaryFile.h; sourceTree = "<group>"; }; | |||||
| 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_CoreGraphicsContext.mm; sourceTree = "<group>"; }; | 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_CoreGraphicsContext.mm; sourceTree = "<group>"; }; | ||||
| 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_HeapBlock.h; sourceTree = "<group>"; }; | 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_HeapBlock.h; sourceTree = "<group>"; }; | ||||
| 84F1E6DC10403605006A1807 /* juce_Application.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Application.cpp; path = ../../src/application/juce_Application.cpp; sourceTree = SOURCE_ROOT; }; | 84F1E6DC10403605006A1807 /* juce_Application.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Application.cpp; path = ../../src/application/juce_Application.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| @@ -2325,6 +2329,8 @@ | |||||
| 84F1E993104036D6006A1807 /* juce_FileSearchPath.h */, | 84F1E993104036D6006A1807 /* juce_FileSearchPath.h */, | ||||
| 84F1E994104036D6006A1807 /* juce_NamedPipe.cpp */, | 84F1E994104036D6006A1807 /* juce_NamedPipe.cpp */, | ||||
| 84F1E995104036D6006A1807 /* juce_NamedPipe.h */, | 84F1E995104036D6006A1807 /* juce_NamedPipe.h */, | ||||
| 84CABF671101292D0088D64D /* juce_TemporaryFile.cpp */, | |||||
| 84CABF681101292D0088D64D /* juce_TemporaryFile.h */, | |||||
| 84F1E996104036D6006A1807 /* juce_ZipFile.cpp */, | 84F1E996104036D6006A1807 /* juce_ZipFile.cpp */, | ||||
| 84F1E997104036D6006A1807 /* juce_ZipFile.h */, | 84F1E997104036D6006A1807 /* juce_ZipFile.h */, | ||||
| ); | ); | ||||
| @@ -3550,6 +3556,7 @@ | |||||
| 84AF3FE810EF9FF30035D74F /* juce_ScopedPointer.h in Headers */, | 84AF3FE810EF9FF30035D74F /* juce_ScopedPointer.h in Headers */, | ||||
| 84BA604110F2017A001D9D70 /* juce_Value.h in Headers */, | 84BA604110F2017A001D9D70 /* juce_Value.h in Headers */, | ||||
| 848432C310F933B800490977 /* juce_ByteOrder.h in Headers */, | 848432C310F933B800490977 /* juce_ByteOrder.h in Headers */, | ||||
| 84CABF6A1101292D0088D64D /* juce_TemporaryFile.h in Headers */, | |||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| @@ -4190,6 +4197,7 @@ | |||||
| 84F29A9F10C2EFA5005014DF /* juce_FillType.cpp in Sources */, | 84F29A9F10C2EFA5005014DF /* juce_FillType.cpp in Sources */, | ||||
| 843D4A3B10D3C54500624BA6 /* juce_ValueTree.cpp in Sources */, | 843D4A3B10D3C54500624BA6 /* juce_ValueTree.cpp in Sources */, | ||||
| 84BA604010F2017A001D9D70 /* juce_Value.cpp in Sources */, | 84BA604010F2017A001D9D70 /* juce_Value.cpp in Sources */, | ||||
| 84CABF691101292D0088D64D /* juce_TemporaryFile.cpp in Sources */, | |||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| @@ -2604,6 +2604,14 @@ | |||||
| RelativePath="..\..\..\src\io\files\juce_NamedPipe.h" | RelativePath="..\..\..\src\io\files\juce_NamedPipe.h" | ||||
| > | > | ||||
| </File> | </File> | ||||
| <File | |||||
| RelativePath="..\..\..\src\io\files\juce_TemporaryFile.cpp" | |||||
| > | |||||
| </File> | |||||
| <File | |||||
| RelativePath="..\..\..\src\io\files\juce_TemporaryFile.h" | |||||
| > | |||||
| </File> | |||||
| <File | <File | ||||
| RelativePath="..\..\..\src\io\files\juce_ZipFile.cpp" | RelativePath="..\..\..\src\io\files\juce_ZipFile.cpp" | ||||
| > | > | ||||
| @@ -1333,7 +1333,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() | |||||
| // Some simple test code to keep an eye on things and make sure these functions | // Some simple test code to keep an eye on things and make sure these functions | ||||
| // work ok on all platforms. Let me know if any of these assertions fail! | // work ok on all platforms. Let me know if any of these assertions fail! | ||||
| jassert (sizeof (pointer_sized_int) == sizeof (void*)); | |||||
| static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); | |||||
| char a1[7]; | char a1[7]; | ||||
| jassert (numElementsInArray(a1) == 7); | jassert (numElementsInArray(a1) == 7); | ||||
| @@ -6664,16 +6664,9 @@ bool File::replaceWithData (const void* const dataToWrite, | |||||
| if (numberOfBytes <= 0) | if (numberOfBytes <= 0) | ||||
| return deleteFile(); | return deleteFile(); | ||||
| const File tempFile (getSiblingFile (T(".") + getFileName()).getNonexistentSibling (false)); | |||||
| if (tempFile.appendData (dataToWrite, numberOfBytes) | |||||
| && tempFile.moveFileTo (*this)) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| tempFile.deleteFile(); | |||||
| return false; | |||||
| TemporaryFile tempFile (*this, TemporaryFile::useHiddenFile); | |||||
| tempFile.getFile().appendData (dataToWrite, numberOfBytes); | |||||
| return tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| bool File::appendText (const String& text, | bool File::appendText (const String& text, | ||||
| @@ -6695,16 +6688,9 @@ bool File::replaceWithText (const String& textToWrite, | |||||
| const bool asUnicode, | const bool asUnicode, | ||||
| const bool writeUnicodeHeaderBytes) const | const bool writeUnicodeHeaderBytes) const | ||||
| { | { | ||||
| const File tempFile (getSiblingFile (T(".") + getFileName()).getNonexistentSibling (false)); | |||||
| if (tempFile.appendText (textToWrite, asUnicode, writeUnicodeHeaderBytes) | |||||
| && tempFile.moveFileTo (*this)) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| tempFile.deleteFile(); | |||||
| return false; | |||||
| TemporaryFile tempFile (*this, TemporaryFile::useHiddenFile); | |||||
| tempFile.getFile().appendText (textToWrite, asUnicode, writeUnicodeHeaderBytes); | |||||
| return tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| const String File::createLegalPathName (const String& original) | const String File::createLegalPathName (const String& original) | ||||
| @@ -6832,12 +6818,9 @@ int File::getVolumeSerialNumber() const | |||||
| const File File::createTempFile (const String& fileNameEnding) | const File File::createTempFile (const String& fileNameEnding) | ||||
| { | { | ||||
| String tempName (T("temp")); | |||||
| static int tempNum = 0; | |||||
| tempName << tempNum++ << fileNameEnding; | |||||
| const File tempFile (getSpecialLocation (tempDirectory) | const File tempFile (getSpecialLocation (tempDirectory) | ||||
| .getChildFile (tempName)); | |||||
| .getChildFile (T("temp_") + String (Random::getSystemRandom().nextInt())) | |||||
| .withFileExtension (fileNameEnding)); | |||||
| if (tempFile.exists()) | if (tempFile.exists()) | ||||
| return createTempFile (fileNameEnding); | return createTempFile (fileNameEnding); | ||||
| @@ -7219,6 +7202,90 @@ const String NamedPipe::getName() const | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| /********* End of inlined file: juce_NamedPipe.cpp *********/ | /********* End of inlined file: juce_NamedPipe.cpp *********/ | ||||
| /********* Start of inlined file: juce_TemporaryFile.cpp *********/ | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| TemporaryFile::TemporaryFile (const String& suffix, const int optionFlags) | |||||
| { | |||||
| createTempFile (File::getSpecialLocation (File::tempDirectory), | |||||
| T("temp_") + String (Random::getSystemRandom().nextInt()), | |||||
| suffix, | |||||
| optionFlags); | |||||
| } | |||||
| TemporaryFile::TemporaryFile (const File& targetFile_, const int optionFlags) | |||||
| : targetFile (targetFile_) | |||||
| { | |||||
| // If you use this constructor, you need to give it a valid target file! | |||||
| jassert (targetFile != File::nonexistent); | |||||
| createTempFile (targetFile.getParentDirectory(), | |||||
| targetFile.getFileNameWithoutExtension() + T("_temp") + String (Random::getSystemRandom().nextInt()), | |||||
| targetFile.getFileExtension(), | |||||
| optionFlags); | |||||
| } | |||||
| void TemporaryFile::createTempFile (const File& parentDirectory, String name, | |||||
| const String& suffix, const int optionFlags) | |||||
| { | |||||
| if ((optionFlags & useHiddenFile) != 0) | |||||
| name = T(".") + name; | |||||
| temporaryFile = parentDirectory.getNonexistentChildFile (name, targetFile.getFileExtension(), | |||||
| (optionFlags & putNumbersInBrackets) != 0); | |||||
| } | |||||
| TemporaryFile::~TemporaryFile() | |||||
| { | |||||
| // Have a few attempts at deleting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| { | |||||
| if (temporaryFile.deleteFile()) | |||||
| return; | |||||
| Thread::sleep (50); | |||||
| } | |||||
| // Failed to delete our temporary file! Check that you've deleted all the | |||||
| // file output streams that were using it! | |||||
| jassertfalse; | |||||
| } | |||||
| bool TemporaryFile::overwriteTargetFileWithTemporary() const | |||||
| { | |||||
| // This method only works if you created this object with the constructor | |||||
| // that takes a target file! | |||||
| jassert (targetFile != File::nonexistent); | |||||
| if (temporaryFile.exists()) | |||||
| { | |||||
| // Have a few attempts at overwriting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| { | |||||
| if (temporaryFile.moveFileTo (targetFile)) | |||||
| return true; | |||||
| Thread::sleep (100); | |||||
| } | |||||
| // Failed to overwrite the new file! Make sure you've not left any | |||||
| // file streams hanging around when you call this method! | |||||
| jassertfalse | |||||
| } | |||||
| else | |||||
| { | |||||
| // There's no temporary file to use. If your write failed, you should | |||||
| // probably check, and not bother calling this method. | |||||
| jassertfalse | |||||
| } | |||||
| return false; | |||||
| } | |||||
| END_JUCE_NAMESPACE | |||||
| /********* End of inlined file: juce_TemporaryFile.cpp *********/ | |||||
| /********* Start of inlined file: juce_Socket.cpp *********/ | /********* Start of inlined file: juce_Socket.cpp *********/ | ||||
| #if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
| @@ -14418,34 +14485,15 @@ bool XmlElement::writeToFile (const File& file, | |||||
| { | { | ||||
| if (file.hasWriteAccess()) | if (file.hasWriteAccess()) | ||||
| { | { | ||||
| const File tempFile (file.getNonexistentSibling()); | |||||
| ScopedPointer <FileOutputStream> out (tempFile.createOutputStream()); | |||||
| TemporaryFile tempFile (file); | |||||
| ScopedPointer <FileOutputStream> out (tempFile.getFile().createOutputStream()); | |||||
| if (out != 0) | if (out != 0) | ||||
| { | { | ||||
| writeToStream (*out, dtdToUse, false, true, encodingType, lineWrapLength); | writeToStream (*out, dtdToUse, false, true, encodingType, lineWrapLength); | ||||
| out = 0; | out = 0; | ||||
| if (! tempFile.exists()) | |||||
| return false; | |||||
| int i; | |||||
| for (i = 5; --i >= 0;) | |||||
| { | |||||
| if (tempFile.moveFileTo (file)) | |||||
| return true; | |||||
| Thread::sleep (100); | |||||
| } | |||||
| for (i = 5; --i >= 0;) | |||||
| { | |||||
| if (tempFile.deleteFile()) | |||||
| break; | |||||
| Thread::sleep (100); | |||||
| } | |||||
| return tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -18173,8 +18221,9 @@ bool PropertiesFile::save() | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const File tempFile (file.getNonexistentSibling (false)); | |||||
| ScopedPointer <OutputStream> out (tempFile.createOutputStream()); | |||||
| TemporaryFile tempFile (file); | |||||
| ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream()); | |||||
| if (out != 0) | if (out != 0) | ||||
| { | { | ||||
| @@ -18203,16 +18252,13 @@ bool PropertiesFile::save() | |||||
| out->writeString (getAllProperties().getAllValues() [i]); | out->writeString (getAllProperties().getAllValues() [i]); | ||||
| } | } | ||||
| out->flush(); | |||||
| out = 0; | out = 0; | ||||
| if (tempFile.moveFileTo (file)) | |||||
| if (tempFile.overwriteTargetFileWithTemporary()) | |||||
| { | { | ||||
| needsWriting = false; | needsWriting = false; | ||||
| return true; | return true; | ||||
| } | } | ||||
| tempFile.deleteFile(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -22398,40 +22444,34 @@ AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out, | |||||
| static bool juce_slowCopyOfWavFileWithNewMetadata (const File& file, const StringPairArray& metadata) | static bool juce_slowCopyOfWavFileWithNewMetadata (const File& file, const StringPairArray& metadata) | ||||
| { | { | ||||
| bool ok = false; | |||||
| WavAudioFormat wav; | |||||
| TemporaryFile tempFile (file); | |||||
| const File dest (file.getNonexistentSibling()); | |||||
| WavAudioFormat wav; | |||||
| ScopedPointer <AudioFormatReader> reader (wav.createReaderFor (file.createInputStream(), true)); | |||||
| if (reader != 0) | |||||
| { | { | ||||
| ScopedPointer <OutputStream> outStream (dest.createOutputStream()); | |||||
| ScopedPointer <OutputStream> outStream (tempFile.getFile().createOutputStream()); | |||||
| if (outStream != 0) | if (outStream != 0) | ||||
| { | { | ||||
| ScopedPointer <AudioFormatReader> reader (wav.createReaderFor (file.createInputStream(), true)); | |||||
| ScopedPointer <AudioFormatWriter> writer (wav.createWriterFor (outStream, reader->sampleRate, | |||||
| reader->numChannels, reader->bitsPerSample, | |||||
| metadata, 0)); | |||||
| if (reader != 0) | |||||
| if (writer != 0) | |||||
| { | { | ||||
| ScopedPointer <AudioFormatWriter> writer (wav.createWriterFor (outStream, reader->sampleRate, | |||||
| reader->numChannels, reader->bitsPerSample, | |||||
| metadata, 0)); | |||||
| outStream.release(); | |||||
| if (writer != 0) | |||||
| { | |||||
| ok = writer->writeFromAudioReader (*reader, 0, -1); | |||||
| outStream.release(); | |||||
| } | |||||
| bool ok = writer->writeFromAudioReader (*reader, 0, -1); | |||||
| writer = 0; | |||||
| return ok && tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (ok) | |||||
| ok = dest.moveFileTo (file); | |||||
| if (! ok) | |||||
| dest.deleteFile(); | |||||
| return ok; | |||||
| return false; | |||||
| } | } | ||||
| bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata) | bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata) | ||||
| @@ -47073,7 +47113,7 @@ Label::Label (const String& componentName, | |||||
| font (15.0f), | font (15.0f), | ||||
| justification (Justification::centredLeft), | justification (Justification::centredLeft), | ||||
| ownerComponent (0), | ownerComponent (0), | ||||
| horizontalBorderSize (3), | |||||
| horizontalBorderSize (5), | |||||
| verticalBorderSize (1), | verticalBorderSize (1), | ||||
| minimumHorizontalScale (0.7f), | minimumHorizontalScale (0.7f), | ||||
| editSingleClick (false), | editSingleClick (false), | ||||
| @@ -81065,10 +81105,6 @@ END_JUCE_NAMESPACE | |||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| #if JUCE_MSVC | |||||
| #pragma warning (disable: 4996) // deprecated sprintf warning | |||||
| #endif | |||||
| // this will throw an assertion if you try to draw something that's not | // this will throw an assertion if you try to draw something that's not | ||||
| // possible in postscript | // possible in postscript | ||||
| #define WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS 0 | #define WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS 0 | ||||
| @@ -213263,11 +213299,10 @@ const String File::getVersion() const | |||||
| if (VerQueryValue (buffer, _T("\\"), (LPVOID*) &vffi, &len)) | if (VerQueryValue (buffer, _T("\\"), (LPVOID*) &vffi, &len)) | ||||
| { | { | ||||
| result.printf (T("%d.%d.%d.%d"), | |||||
| HIWORD (vffi->dwFileVersionMS), | |||||
| LOWORD (vffi->dwFileVersionMS), | |||||
| HIWORD (vffi->dwFileVersionLS), | |||||
| LOWORD (vffi->dwFileVersionLS)); | |||||
| result << (int) HIWORD (vffi->dwFileVersionMS) << "." | |||||
| << (int) LOWORD (vffi->dwFileVersionMS) << "." | |||||
| << (int) HIWORD (vffi->dwFileVersionLS) << "." | |||||
| << (int) LOWORD (vffi->dwFileVersionLS); | |||||
| } | } | ||||
| } | } | ||||
| @@ -213905,6 +213940,12 @@ static int getMACAddressViaGetAdaptersInfo (int64* addresses, int maxNum, const | |||||
| return numFound; | return numFound; | ||||
| } | } | ||||
| struct ASTAT | |||||
| { | |||||
| ADAPTER_STATUS adapt; | |||||
| NAME_BUFFER NameBuff [30]; | |||||
| }; | |||||
| static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool littleEndian) throw() | static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool littleEndian) throw() | ||||
| { | { | ||||
| int numFound = 0; | int numFound = 0; | ||||
| @@ -213917,12 +213958,6 @@ static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool l | |||||
| NCB ncb; | NCB ncb; | ||||
| zerostruct (ncb); | zerostruct (ncb); | ||||
| typedef struct _ASTAT_ | |||||
| { | |||||
| ADAPTER_STATUS adapt; | |||||
| NAME_BUFFER NameBuff [30]; | |||||
| } ASTAT; | |||||
| ASTAT astat; | ASTAT astat; | ||||
| zerostruct (astat); | zerostruct (astat); | ||||
| @@ -7601,6 +7601,55 @@ private: | |||||
| #endif // __JUCE_NAMEDPIPE_JUCEHEADER__ | #endif // __JUCE_NAMEDPIPE_JUCEHEADER__ | ||||
| /********* End of inlined file: juce_NamedPipe.h *********/ | /********* End of inlined file: juce_NamedPipe.h *********/ | ||||
| #endif | |||||
| #ifndef __JUCE_TEMPORARYFILE_JUCEHEADER__ | |||||
| /********* Start of inlined file: juce_TemporaryFile.h *********/ | |||||
| #ifndef __JUCE_TEMPORARYFILE_JUCEHEADER__ | |||||
| #define __JUCE_TEMPORARYFILE_JUCEHEADER__ | |||||
| class JUCE_API TemporaryFile | |||||
| { | |||||
| public: | |||||
| enum OptionFlags | |||||
| { | |||||
| useHiddenFile = 1, /**< Indicates that the temporary file should be hidden - | |||||
| i.e. its name should start with a dot. */ | |||||
| putNumbersInBrackets = 2 /**< Indicates that when numbers are appended to make sure | |||||
| the file is unique, they should go in brackets rather | |||||
| than just being appended (see File::getNonexistentSibling() )*/ | |||||
| }; | |||||
| TemporaryFile (const String& suffix = String::empty, | |||||
| const int optionFlags = 0); | |||||
| TemporaryFile (const File& targetFile, | |||||
| const int optionFlags = 0); | |||||
| ~TemporaryFile(); | |||||
| const File getFile() const { return temporaryFile; } | |||||
| const File getTargetFile() const { return targetFile; } | |||||
| bool overwriteTargetFileWithTemporary() const; | |||||
| juce_UseDebuggingNewOperator | |||||
| private: | |||||
| File temporaryFile, targetFile; | |||||
| void createTempFile (const File& parentDirectory, String name, const String& suffix, const int optionFlags); | |||||
| TemporaryFile (const TemporaryFile&); | |||||
| const TemporaryFile& operator= (const TemporaryFile&); | |||||
| }; | |||||
| #endif // __JUCE_TEMPORARYFILE_JUCEHEADER__ | |||||
| /********* End of inlined file: juce_TemporaryFile.h *********/ | |||||
| #endif | #endif | ||||
| #ifndef __JUCE_ZIPFILE_JUCEHEADER__ | #ifndef __JUCE_ZIPFILE_JUCEHEADER__ | ||||
| @@ -25100,6 +25149,9 @@ private: | |||||
| String onText, offText; | String onText, offText; | ||||
| void createButton(); | void createButton(); | ||||
| BooleanPropertyComponent (const BooleanPropertyComponent&); | |||||
| const BooleanPropertyComponent& operator= (const BooleanPropertyComponent&); | |||||
| }; | }; | ||||
| #endif // __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ | #endif // __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ | ||||
| @@ -25176,6 +25228,9 @@ private: | |||||
| ComboBox* comboBox; | ComboBox* comboBox; | ||||
| void createComboBox(); | void createComboBox(); | ||||
| ChoicePropertyComponent (const ChoicePropertyComponent&); | |||||
| const ChoicePropertyComponent& operator= (const ChoicePropertyComponent&); | |||||
| }; | }; | ||||
| #endif // __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ | #endif // __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ | ||||
| @@ -25229,6 +25284,9 @@ public: | |||||
| protected: | protected: | ||||
| Slider* slider; | Slider* slider; | ||||
| SliderPropertyComponent (const SliderPropertyComponent&); | |||||
| const SliderPropertyComponent& operator= (const SliderPropertyComponent&); | |||||
| }; | }; | ||||
| #endif // __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ | #endif // __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ | ||||
| @@ -25270,6 +25328,9 @@ private: | |||||
| Label* textEditor; | Label* textEditor; | ||||
| void createEditor (const int maxNumChars, const bool isMultiLine); | void createEditor (const int maxNumChars, const bool isMultiLine); | ||||
| TextPropertyComponent (const TextPropertyComponent&); | |||||
| const TextPropertyComponent& operator= (const TextPropertyComponent&); | |||||
| }; | }; | ||||
| #endif // __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ | #endif // __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ | ||||
| @@ -31,7 +31,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../../io/streams/juce_BufferedInputStream.h" | #include "../../io/streams/juce_BufferedInputStream.h" | ||||
| #include "../../text/juce_LocalisedStrings.h" | #include "../../text/juce_LocalisedStrings.h" | ||||
| #include "../../io/files/juce_FileInputStream.h" | #include "../../io/files/juce_FileInputStream.h" | ||||
| #include "../../io/files/juce_FileOutputStream.h" | |||||
| #include "../../io/files/juce_TemporaryFile.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -793,40 +793,34 @@ AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out, | |||||
| static bool juce_slowCopyOfWavFileWithNewMetadata (const File& file, const StringPairArray& metadata) | static bool juce_slowCopyOfWavFileWithNewMetadata (const File& file, const StringPairArray& metadata) | ||||
| { | { | ||||
| bool ok = false; | |||||
| WavAudioFormat wav; | |||||
| TemporaryFile tempFile (file); | |||||
| const File dest (file.getNonexistentSibling()); | |||||
| WavAudioFormat wav; | |||||
| ScopedPointer <AudioFormatReader> reader (wav.createReaderFor (file.createInputStream(), true)); | |||||
| if (reader != 0) | |||||
| { | { | ||||
| ScopedPointer <OutputStream> outStream (dest.createOutputStream()); | |||||
| ScopedPointer <OutputStream> outStream (tempFile.getFile().createOutputStream()); | |||||
| if (outStream != 0) | if (outStream != 0) | ||||
| { | { | ||||
| ScopedPointer <AudioFormatReader> reader (wav.createReaderFor (file.createInputStream(), true)); | |||||
| ScopedPointer <AudioFormatWriter> writer (wav.createWriterFor (outStream, reader->sampleRate, | |||||
| reader->numChannels, reader->bitsPerSample, | |||||
| metadata, 0)); | |||||
| if (reader != 0) | |||||
| if (writer != 0) | |||||
| { | { | ||||
| ScopedPointer <AudioFormatWriter> writer (wav.createWriterFor (outStream, reader->sampleRate, | |||||
| reader->numChannels, reader->bitsPerSample, | |||||
| metadata, 0)); | |||||
| outStream.release(); | |||||
| if (writer != 0) | |||||
| { | |||||
| ok = writer->writeFromAudioReader (*reader, 0, -1); | |||||
| outStream.release(); | |||||
| } | |||||
| bool ok = writer->writeFromAudioReader (*reader, 0, -1); | |||||
| writer = 0; | |||||
| return ok && tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (ok) | |||||
| ok = dest.moveFileTo (file); | |||||
| if (! ok) | |||||
| dest.deleteFile(); | |||||
| return ok; | |||||
| return false; | |||||
| } | } | ||||
| bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata) | bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata) | ||||
| @@ -63,7 +63,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() | |||||
| // Some simple test code to keep an eye on things and make sure these functions | // Some simple test code to keep an eye on things and make sure these functions | ||||
| // work ok on all platforms. Let me know if any of these assertions fail! | // work ok on all platforms. Let me know if any of these assertions fail! | ||||
| jassert (sizeof (pointer_sized_int) == sizeof (void*)); | |||||
| static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); | |||||
| char a1[7]; | char a1[7]; | ||||
| jassert (numElementsInArray(a1) == 7); | jassert (numElementsInArray(a1) == 7); | ||||
| @@ -40,7 +40,7 @@ Label::Label (const String& componentName, | |||||
| font (15.0f), | font (15.0f), | ||||
| justification (Justification::centredLeft), | justification (Justification::centredLeft), | ||||
| ownerComponent (0), | ownerComponent (0), | ||||
| horizontalBorderSize (3), | |||||
| horizontalBorderSize (5), | |||||
| verticalBorderSize (1), | verticalBorderSize (1), | ||||
| minimumHorizontalScale (0.7f), | minimumHorizontalScale (0.7f), | ||||
| editSingleClick (false), | editSingleClick (false), | ||||
| @@ -93,6 +93,9 @@ private: | |||||
| String onText, offText; | String onText, offText; | ||||
| void createButton(); | void createButton(); | ||||
| BooleanPropertyComponent (const BooleanPropertyComponent&); | |||||
| const BooleanPropertyComponent& operator= (const BooleanPropertyComponent&); | |||||
| }; | }; | ||||
| @@ -114,6 +114,9 @@ private: | |||||
| ComboBox* comboBox; | ComboBox* comboBox; | ||||
| void createComboBox(); | void createComboBox(); | ||||
| ChoicePropertyComponent (const ChoicePropertyComponent&); | |||||
| const ChoicePropertyComponent& operator= (const ChoicePropertyComponent&); | |||||
| }; | }; | ||||
| @@ -103,6 +103,9 @@ protected: | |||||
| Your subclass has access to this in case it needs to customise it in some way. | Your subclass has access to this in case it needs to customise it in some way. | ||||
| */ | */ | ||||
| Slider* slider; | Slider* slider; | ||||
| SliderPropertyComponent (const SliderPropertyComponent&); | |||||
| const SliderPropertyComponent& operator= (const SliderPropertyComponent&); | |||||
| }; | }; | ||||
| @@ -92,6 +92,9 @@ private: | |||||
| Label* textEditor; | Label* textEditor; | ||||
| void createEditor (const int maxNumChars, const bool isMultiLine); | void createEditor (const int maxNumChars, const bool isMultiLine); | ||||
| TextPropertyComponent (const TextPropertyComponent&); | |||||
| const TextPropertyComponent& operator= (const TextPropertyComponent&); | |||||
| }; | }; | ||||
| @@ -34,11 +34,6 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../geometry/juce_Rectangle.h" | #include "../geometry/juce_Rectangle.h" | ||||
| #include "../../../containers/juce_SparseSet.h" | #include "../../../containers/juce_SparseSet.h" | ||||
| #if JUCE_MSVC | |||||
| #pragma warning (disable: 4996) // deprecated sprintf warning | |||||
| #endif | |||||
| // this will throw an assertion if you try to draw something that's not | // this will throw an assertion if you try to draw something that's not | ||||
| // possible in postscript | // possible in postscript | ||||
| #define WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS 0 | #define WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS 0 | ||||
| @@ -39,8 +39,9 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_File.h" | #include "juce_File.h" | ||||
| #include "juce_FileInputStream.h" | #include "juce_FileInputStream.h" | ||||
| #include "juce_FileOutputStream.h" | |||||
| #include "juce_TemporaryFile.h" | |||||
| #include "../../core/juce_SystemStats.h" | #include "../../core/juce_SystemStats.h" | ||||
| #include "../../core/juce_Random.h" | |||||
| #ifdef _MSC_VER | #ifdef _MSC_VER | ||||
| #pragma warning (pop) | #pragma warning (pop) | ||||
| @@ -958,16 +959,9 @@ bool File::replaceWithData (const void* const dataToWrite, | |||||
| if (numberOfBytes <= 0) | if (numberOfBytes <= 0) | ||||
| return deleteFile(); | return deleteFile(); | ||||
| const File tempFile (getSiblingFile (T(".") + getFileName()).getNonexistentSibling (false)); | |||||
| if (tempFile.appendData (dataToWrite, numberOfBytes) | |||||
| && tempFile.moveFileTo (*this)) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| tempFile.deleteFile(); | |||||
| return false; | |||||
| TemporaryFile tempFile (*this, TemporaryFile::useHiddenFile); | |||||
| tempFile.getFile().appendData (dataToWrite, numberOfBytes); | |||||
| return tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| bool File::appendText (const String& text, | bool File::appendText (const String& text, | ||||
| @@ -989,16 +983,9 @@ bool File::replaceWithText (const String& textToWrite, | |||||
| const bool asUnicode, | const bool asUnicode, | ||||
| const bool writeUnicodeHeaderBytes) const | const bool writeUnicodeHeaderBytes) const | ||||
| { | { | ||||
| const File tempFile (getSiblingFile (T(".") + getFileName()).getNonexistentSibling (false)); | |||||
| if (tempFile.appendText (textToWrite, asUnicode, writeUnicodeHeaderBytes) | |||||
| && tempFile.moveFileTo (*this)) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| tempFile.deleteFile(); | |||||
| return false; | |||||
| TemporaryFile tempFile (*this, TemporaryFile::useHiddenFile); | |||||
| tempFile.getFile().appendText (textToWrite, asUnicode, writeUnicodeHeaderBytes); | |||||
| return tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -1130,12 +1117,9 @@ int File::getVolumeSerialNumber() const | |||||
| //============================================================================== | //============================================================================== | ||||
| const File File::createTempFile (const String& fileNameEnding) | const File File::createTempFile (const String& fileNameEnding) | ||||
| { | { | ||||
| String tempName (T("temp")); | |||||
| static int tempNum = 0; | |||||
| tempName << tempNum++ << fileNameEnding; | |||||
| const File tempFile (getSpecialLocation (tempDirectory) | const File tempFile (getSpecialLocation (tempDirectory) | ||||
| .getChildFile (tempName)); | |||||
| .getChildFile (T("temp_") + String (Random::getSystemRandom().nextInt())) | |||||
| .withFileExtension (fileNameEnding)); | |||||
| if (tempFile.exists()) | if (tempFile.exists()) | ||||
| return createTempFile (fileNameEnding); | return createTempFile (fileNameEnding); | ||||
| @@ -53,6 +53,8 @@ public: | |||||
| It's better to use File::createOutputStream() to create one of these, rather | It's better to use File::createOutputStream() to create one of these, rather | ||||
| than using the class directly. | than using the class directly. | ||||
| @see TemporaryFile | |||||
| */ | */ | ||||
| FileOutputStream (const File& fileToWriteTo, | FileOutputStream (const File& fileToWriteTo, | ||||
| const int bufferSizeToUse = 16384); | const int bufferSizeToUse = 16384); | ||||
| @@ -0,0 +1,115 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-9 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 "../../core/juce_StandardHeader.h" | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_TemporaryFile.h" | |||||
| #include "../../core/juce_Random.h" | |||||
| #include "../../threads/juce_Thread.h" | |||||
| //============================================================================== | |||||
| TemporaryFile::TemporaryFile (const String& suffix, const int optionFlags) | |||||
| { | |||||
| createTempFile (File::getSpecialLocation (File::tempDirectory), | |||||
| T("temp_") + String (Random::getSystemRandom().nextInt()), | |||||
| suffix, | |||||
| optionFlags); | |||||
| } | |||||
| TemporaryFile::TemporaryFile (const File& targetFile_, const int optionFlags) | |||||
| : targetFile (targetFile_) | |||||
| { | |||||
| // If you use this constructor, you need to give it a valid target file! | |||||
| jassert (targetFile != File::nonexistent); | |||||
| createTempFile (targetFile.getParentDirectory(), | |||||
| targetFile.getFileNameWithoutExtension() + T("_temp") + String (Random::getSystemRandom().nextInt()), | |||||
| targetFile.getFileExtension(), | |||||
| optionFlags); | |||||
| } | |||||
| void TemporaryFile::createTempFile (const File& parentDirectory, String name, | |||||
| const String& suffix, const int optionFlags) | |||||
| { | |||||
| if ((optionFlags & useHiddenFile) != 0) | |||||
| name = T(".") + name; | |||||
| temporaryFile = parentDirectory.getNonexistentChildFile (name, targetFile.getFileExtension(), | |||||
| (optionFlags & putNumbersInBrackets) != 0); | |||||
| } | |||||
| TemporaryFile::~TemporaryFile() | |||||
| { | |||||
| // Have a few attempts at deleting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| { | |||||
| if (temporaryFile.deleteFile()) | |||||
| return; | |||||
| Thread::sleep (50); | |||||
| } | |||||
| // Failed to delete our temporary file! Check that you've deleted all the | |||||
| // file output streams that were using it! | |||||
| jassertfalse; | |||||
| } | |||||
| //============================================================================== | |||||
| bool TemporaryFile::overwriteTargetFileWithTemporary() const | |||||
| { | |||||
| // This method only works if you created this object with the constructor | |||||
| // that takes a target file! | |||||
| jassert (targetFile != File::nonexistent); | |||||
| if (temporaryFile.exists()) | |||||
| { | |||||
| // Have a few attempts at overwriting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| { | |||||
| if (temporaryFile.moveFileTo (targetFile)) | |||||
| return true; | |||||
| Thread::sleep (100); | |||||
| } | |||||
| // Failed to overwrite the new file! Make sure you've not left any | |||||
| // file streams hanging around when you call this method! | |||||
| jassertfalse | |||||
| } | |||||
| else | |||||
| { | |||||
| // There's no temporary file to use. If your write failed, you should | |||||
| // probably check, and not bother calling this method. | |||||
| jassertfalse | |||||
| } | |||||
| return false; | |||||
| } | |||||
| END_JUCE_NAMESPACE | |||||
| @@ -0,0 +1,159 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-9 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_TEMPORARYFILE_JUCEHEADER__ | |||||
| #define __JUCE_TEMPORARYFILE_JUCEHEADER__ | |||||
| #include "juce_FileOutputStream.h" | |||||
| //============================================================================== | |||||
| /** | |||||
| Manages a temporary file, which will be deleted when this object is deleted. | |||||
| This object is intended to be used as a stack based object, using its scope | |||||
| to make sure the temporary file isn't left lying around. | |||||
| For example: | |||||
| @code | |||||
| { | |||||
| File myTargetFile ("~/myfile.txt"); | |||||
| // this will choose a file called something like "~/myfile_temp239348.txt" | |||||
| // which definitely doesn't exist at the time the constructor is called. | |||||
| TemporaryFile temp (myTargetFile); | |||||
| // create a stream to the temporary file, and write some data to it... | |||||
| ScopedPointer <FileOutputStream> out (temp.getFile().createOutputStream()); | |||||
| if (out != 0) | |||||
| { | |||||
| out->write ( ...etc ) | |||||
| out->flush(); | |||||
| out = 0; // (deletes the stream) | |||||
| // ..now we've finished writing, this will rename the temp file to | |||||
| // make it replace the target file we specified above. | |||||
| bool succeeded = temp.overwriteTargetFileWithTemporary(); | |||||
| } | |||||
| // ..and even if something went wrong and our overwrite failed, | |||||
| // as the TemporaryFile object goes out of scope here, it'll make sure | |||||
| // that the temp file gets deleted. | |||||
| } | |||||
| @endcode | |||||
| @see File, FileOutputStream | |||||
| */ | |||||
| class JUCE_API TemporaryFile | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| enum OptionFlags | |||||
| { | |||||
| useHiddenFile = 1, /**< Indicates that the temporary file should be hidden - | |||||
| i.e. its name should start with a dot. */ | |||||
| putNumbersInBrackets = 2 /**< Indicates that when numbers are appended to make sure | |||||
| the file is unique, they should go in brackets rather | |||||
| than just being appended (see File::getNonexistentSibling() )*/ | |||||
| }; | |||||
| //============================================================================== | |||||
| /** Creates a randomly-named temporary file in the default temp directory. | |||||
| @param suffix a file suffix to use for the file | |||||
| @param optionFlags a combination of the values listed in the OptionFlags enum | |||||
| The file will not be created until you write to it. And remember that when | |||||
| this object is deleted, the file will also be deleted! | |||||
| */ | |||||
| TemporaryFile (const String& suffix = String::empty, | |||||
| const int optionFlags = 0); | |||||
| /** Creates a temporary file in the same directory as a specified file. | |||||
| This is useful if you have a file that you want to overwrite, but don't | |||||
| want to harm the original file if the write operation fails. You can | |||||
| use this to create a temporary file next to the target file, then | |||||
| write to the temporary file, and finally use overwriteTargetFileWithTemporary() | |||||
| to replace the target file with the one you've just written. | |||||
| This class won't create any files until you actually write to them. And remember | |||||
| that when this object is deleted, the temporary file will also be deleted! | |||||
| @param targetFile the file that you intend to overwrite - the temporary | |||||
| file will be created in the same directory as this | |||||
| @param optionFlags a combination of the values listed in the OptionFlags enum | |||||
| */ | |||||
| TemporaryFile (const File& targetFile, | |||||
| const int optionFlags = 0); | |||||
| /** Destructor. | |||||
| When this object is deleted it will make sure that its temporary file is | |||||
| also deleted! If the operation fails, it'll throw an assertion in debug | |||||
| mode. | |||||
| */ | |||||
| ~TemporaryFile(); | |||||
| //============================================================================== | |||||
| /** Returns the temporary file. */ | |||||
| const File getFile() const { return temporaryFile; } | |||||
| /** Returns the target file that was specified in the constructor. */ | |||||
| const File getTargetFile() const { return targetFile; } | |||||
| /** Tries to move the temporary file to overwrite the target file that was | |||||
| specified in the constructor. | |||||
| If you used the constructor that specified a target file, this will attempt | |||||
| to replace that file with the temporary one. | |||||
| Before calling this, make sure: | |||||
| - that you've actually written to the temporary file | |||||
| - that you've closed any open streams that you were using to write to it | |||||
| - and that you don't have any streams open to the target file, which would | |||||
| prevent it being overwritten | |||||
| If the file move succeeds, this returns false, and the temporary file will | |||||
| have disappeared. If it fails, the temporary file will probably still exist, | |||||
| but will be deleted when this object is destroyed. | |||||
| */ | |||||
| bool overwriteTargetFileWithTemporary() const; | |||||
| //============================================================================== | |||||
| juce_UseDebuggingNewOperator | |||||
| private: | |||||
| //============================================================================== | |||||
| File temporaryFile, targetFile; | |||||
| void createTempFile (const File& parentDirectory, String name, const String& suffix, const int optionFlags); | |||||
| TemporaryFile (const TemporaryFile&); | |||||
| const TemporaryFile& operator= (const TemporaryFile&); | |||||
| }; | |||||
| #endif // __JUCE_TEMPORARYFILE_JUCEHEADER__ | |||||
| @@ -94,6 +94,7 @@ | |||||
| #include "io/files/juce_FileOutputStream.cpp" | #include "io/files/juce_FileOutputStream.cpp" | ||||
| #include "io/files/juce_FileSearchPath.cpp" | #include "io/files/juce_FileSearchPath.cpp" | ||||
| #include "io/files/juce_NamedPipe.cpp" | #include "io/files/juce_NamedPipe.cpp" | ||||
| #include "io/files/juce_TemporaryFile.cpp" | |||||
| #include "io/network/juce_Socket.cpp" | #include "io/network/juce_Socket.cpp" | ||||
| #include "io/network/juce_URL.cpp" | #include "io/network/juce_URL.cpp" | ||||
| #include "io/streams/juce_BufferedInputStream.cpp" | #include "io/streams/juce_BufferedInputStream.cpp" | ||||
| @@ -161,6 +161,9 @@ | |||||
| #ifndef __JUCE_NAMEDPIPE_JUCEHEADER__ | #ifndef __JUCE_NAMEDPIPE_JUCEHEADER__ | ||||
| #include "io/files/juce_NamedPipe.h" | #include "io/files/juce_NamedPipe.h" | ||||
| #endif | #endif | ||||
| #ifndef __JUCE_TEMPORARYFILE_JUCEHEADER__ | |||||
| #include "io/files/juce_TemporaryFile.h" | |||||
| #endif | |||||
| #ifndef __JUCE_ZIPFILE_JUCEHEADER__ | #ifndef __JUCE_ZIPFILE_JUCEHEADER__ | ||||
| #include "io/files/juce_ZipFile.h" | #include "io/files/juce_ZipFile.h" | ||||
| #endif | #endif | ||||
| @@ -540,11 +540,10 @@ const String File::getVersion() const | |||||
| if (VerQueryValue (buffer, _T("\\"), (LPVOID*) &vffi, &len)) | if (VerQueryValue (buffer, _T("\\"), (LPVOID*) &vffi, &len)) | ||||
| { | { | ||||
| result.printf (T("%d.%d.%d.%d"), | |||||
| HIWORD (vffi->dwFileVersionMS), | |||||
| LOWORD (vffi->dwFileVersionMS), | |||||
| HIWORD (vffi->dwFileVersionLS), | |||||
| LOWORD (vffi->dwFileVersionLS)); | |||||
| result << (int) HIWORD (vffi->dwFileVersionMS) << "." | |||||
| << (int) LOWORD (vffi->dwFileVersionMS) << "." | |||||
| << (int) HIWORD (vffi->dwFileVersionLS) << "." | |||||
| << (int) LOWORD (vffi->dwFileVersionLS); | |||||
| } | } | ||||
| } | } | ||||
| @@ -289,6 +289,12 @@ static int getMACAddressViaGetAdaptersInfo (int64* addresses, int maxNum, const | |||||
| return numFound; | return numFound; | ||||
| } | } | ||||
| struct ASTAT | |||||
| { | |||||
| ADAPTER_STATUS adapt; | |||||
| NAME_BUFFER NameBuff [30]; | |||||
| }; | |||||
| static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool littleEndian) throw() | static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool littleEndian) throw() | ||||
| { | { | ||||
| int numFound = 0; | int numFound = 0; | ||||
| @@ -301,12 +307,6 @@ static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool l | |||||
| NCB ncb; | NCB ncb; | ||||
| zerostruct (ncb); | zerostruct (ncb); | ||||
| typedef struct _ASTAT_ | |||||
| { | |||||
| ADAPTER_STATUS adapt; | |||||
| NAME_BUFFER NameBuff [30]; | |||||
| } ASTAT; | |||||
| ASTAT astat; | ASTAT astat; | ||||
| zerostruct (astat); | zerostruct (astat); | ||||
| @@ -30,7 +30,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_XmlElement.h" | #include "juce_XmlElement.h" | ||||
| #include "../io/streams/juce_MemoryOutputStream.h" | #include "../io/streams/juce_MemoryOutputStream.h" | ||||
| #include "../io/files/juce_FileOutputStream.h" | |||||
| #include "../io/files/juce_TemporaryFile.h" | |||||
| #include "../threads/juce_Thread.h" | #include "../threads/juce_Thread.h" | ||||
| #include "../containers/juce_ScopedPointer.h" | #include "../containers/juce_ScopedPointer.h" | ||||
| @@ -429,34 +429,15 @@ bool XmlElement::writeToFile (const File& file, | |||||
| { | { | ||||
| if (file.hasWriteAccess()) | if (file.hasWriteAccess()) | ||||
| { | { | ||||
| const File tempFile (file.getNonexistentSibling()); | |||||
| ScopedPointer <FileOutputStream> out (tempFile.createOutputStream()); | |||||
| TemporaryFile tempFile (file); | |||||
| ScopedPointer <FileOutputStream> out (tempFile.getFile().createOutputStream()); | |||||
| if (out != 0) | if (out != 0) | ||||
| { | { | ||||
| writeToStream (*out, dtdToUse, false, true, encodingType, lineWrapLength); | writeToStream (*out, dtdToUse, false, true, encodingType, lineWrapLength); | ||||
| out = 0; | out = 0; | ||||
| if (! tempFile.exists()) | |||||
| return false; | |||||
| int i; | |||||
| for (i = 5; --i >= 0;) | |||||
| { | |||||
| if (tempFile.moveFileTo (file)) | |||||
| return true; | |||||
| Thread::sleep (100); | |||||
| } | |||||
| for (i = 5; --i >= 0;) | |||||
| { | |||||
| if (tempFile.deleteFile()) | |||||
| break; | |||||
| Thread::sleep (100); | |||||
| } | |||||
| return tempFile.overwriteTargetFileWithTemporary(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -29,6 +29,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_PropertiesFile.h" | #include "juce_PropertiesFile.h" | ||||
| #include "../io/files/juce_TemporaryFile.h" | |||||
| #include "../io/files/juce_FileInputStream.h" | #include "../io/files/juce_FileInputStream.h" | ||||
| #include "../io/files/juce_FileOutputStream.h" | #include "../io/files/juce_FileOutputStream.h" | ||||
| #include "../io/streams/juce_BufferedInputStream.h" | #include "../io/streams/juce_BufferedInputStream.h" | ||||
| @@ -182,8 +183,9 @@ bool PropertiesFile::save() | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const File tempFile (file.getNonexistentSibling (false)); | |||||
| ScopedPointer <OutputStream> out (tempFile.createOutputStream()); | |||||
| TemporaryFile tempFile (file); | |||||
| ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream()); | |||||
| if (out != 0) | if (out != 0) | ||||
| { | { | ||||
| @@ -212,16 +214,13 @@ bool PropertiesFile::save() | |||||
| out->writeString (getAllProperties().getAllValues() [i]); | out->writeString (getAllProperties().getAllValues() [i]); | ||||
| } | } | ||||
| out->flush(); | |||||
| out = 0; | out = 0; | ||||
| if (tempFile.moveFileTo (file)) | |||||
| if (tempFile.overwriteTargetFileWithTemporary()) | |||||
| { | { | ||||
| needsWriting = false; | needsWriting = false; | ||||
| return true; | return true; | ||||
| } | } | ||||
| tempFile.deleteFile(); | |||||
| } | } | ||||
| } | } | ||||