Browse Source

Update juce

tags/1.9.4
falkTX 12 years ago
parent
commit
3b9b3d6e78
77 changed files with 1564 additions and 1147 deletions
  1. +2
    -0
      source/backend/plugin/CarlaPluginGui.hpp
  2. +23
    -23
      source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp
  3. +20
    -16
      source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp
  4. +9
    -9
      source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h
  5. +0
    -10
      source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp
  6. +239
    -0
      source/modules/juce_audio_basics/effects/juce_IIRFilterOld.cpp
  7. +148
    -0
      source/modules/juce_audio_basics/effects/juce_IIRFilterOld.h
  8. +1
    -0
      source/modules/juce_audio_basics/juce_audio_basics.cpp
  9. +1
    -0
      source/modules/juce_audio_basics/juce_audio_basics.h
  10. +1
    -1
      source/modules/juce_audio_basics/juce_module_info
  11. +2
    -4
      source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp
  12. +3
    -3
      source/modules/juce_audio_basics/midi/juce_MidiBuffer.h
  13. +29
    -29
      source/modules/juce_audio_basics/midi/juce_MidiFile.cpp
  14. +8
    -14
      source/modules/juce_audio_basics/midi/juce_MidiFile.h
  15. +6
    -1
      source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp
  16. +12
    -23
      source/modules/juce_audio_basics/midi/juce_MidiMessage.h
  17. +2
    -3
      source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp
  18. +17
    -17
      source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp
  19. +2
    -3
      source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp
  20. +15
    -25
      source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp
  21. +25
    -27
      source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h
  22. +4
    -17
      source/modules/juce_core/AppConfig.h
  23. +7
    -6
      source/modules/juce_core/containers/juce_AbstractFifo.cpp
  24. +25
    -7
      source/modules/juce_core/containers/juce_Array.h
  25. +7
    -11
      source/modules/juce_core/containers/juce_PropertySet.cpp
  26. +7
    -11
      source/modules/juce_core/containers/juce_PropertySet.h
  27. +42
    -41
      source/modules/juce_core/files/juce_File.cpp
  28. +6
    -6
      source/modules/juce_core/files/juce_File.h
  29. +16
    -9
      source/modules/juce_core/json/juce_JSON.cpp
  30. +3
    -0
      source/modules/juce_core/json/juce_JSON.h
  31. +3
    -1
      source/modules/juce_core/juce_core.h
  32. +1
    -1
      source/modules/juce_core/juce_module_info
  33. +2
    -2
      source/modules/juce_core/maths/juce_BigInteger.cpp
  34. +1
    -1
      source/modules/juce_core/maths/juce_BigInteger.h
  35. +15
    -21
      source/modules/juce_core/maths/juce_Random.cpp
  36. +4
    -7
      source/modules/juce_core/maths/juce_Random.h
  37. +11
    -13
      source/modules/juce_core/memory/juce_MemoryBlock.cpp
  38. +2
    -2
      source/modules/juce_core/memory/juce_MemoryBlock.h
  39. +8
    -22
      source/modules/juce_core/misc/juce_Uuid.cpp
  40. +8
    -5
      source/modules/juce_core/misc/juce_Uuid.h
  41. +10
    -18
      source/modules/juce_core/native/juce_android_SystemStats.cpp
  42. +8
    -9
      source/modules/juce_core/native/juce_linux_Files.cpp
  43. +5
    -5
      source/modules/juce_core/native/juce_linux_SystemStats.cpp
  44. +2
    -2
      source/modules/juce_core/native/juce_mac_Files.mm
  45. +20
    -16
      source/modules/juce_core/native/juce_mac_Network.mm
  46. +6
    -21
      source/modules/juce_core/native/juce_posix_SharedCode.h
  47. +1
    -1
      source/modules/juce_core/native/juce_win32_Network.cpp
  48. +1
    -1
      source/modules/juce_core/native/juce_win32_Registry.cpp
  49. +25
    -46
      source/modules/juce_core/native/juce_win32_Threads.cpp
  50. +15
    -14
      source/modules/juce_core/network/juce_URL.cpp
  51. +1
    -1
      source/modules/juce_core/network/juce_URL.h
  52. +3
    -4
      source/modules/juce_core/streams/juce_MemoryInputStream.cpp
  53. +3
    -3
      source/modules/juce_core/system/juce_PlatformDefs.h
  54. +1
    -1
      source/modules/juce_core/system/juce_StandardHeader.h
  55. +20
    -0
      source/modules/juce_core/text/juce_CharacterFunctions.h
  56. +4
    -1
      source/modules/juce_core/text/juce_Identifier.h
  57. +8
    -0
      source/modules/juce_core/text/juce_NewLine.h
  58. +255
    -287
      source/modules/juce_core/text/juce_String.cpp
  59. +45
    -38
      source/modules/juce_core/text/juce_String.h
  60. +33
    -85
      source/modules/juce_core/text/juce_StringArray.cpp
  61. +22
    -23
      source/modules/juce_core/text/juce_StringArray.h
  62. +3
    -3
      source/modules/juce_core/text/juce_StringPairArray.cpp
  63. +3
    -9
      source/modules/juce_core/text/juce_StringPairArray.h
  64. +20
    -21
      source/modules/juce_core/text/juce_StringPool.cpp
  65. +135
    -0
      source/modules/juce_core/text/juce_StringRef.h
  66. +6
    -5
      source/modules/juce_core/text/juce_TextDiff.cpp
  67. +6
    -6
      source/modules/juce_core/threads/juce_CriticalSection.h
  68. +2
    -2
      source/modules/juce_core/threads/juce_Process.h
  69. +4
    -7
      source/modules/juce_core/threads/juce_ReadWriteLock.h
  70. +1
    -2
      source/modules/juce_core/threads/juce_WaitableEvent.h
  71. +31
    -8
      source/modules/juce_core/unit_tests/juce_UnitTest.cpp
  72. +25
    -2
      source/modules/juce_core/unit_tests/juce_UnitTest.h
  73. +4
    -2
      source/modules/juce_core/xml/juce_XmlDocument.cpp
  74. +66
    -69
      source/modules/juce_core/xml/juce_XmlElement.cpp
  75. +28
    -43
      source/modules/juce_core/xml/juce_XmlElement.h
  76. +1
    -1
      source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp
  77. +4
    -0
      source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp

+ 2
- 0
source/backend/plugin/CarlaPluginGui.hpp View File

@@ -20,6 +20,8 @@

#include "CarlaPluginInternal.hpp"

#include "juce_gui_basics.h"

#if 0
#include <QtGui/QCloseEvent>



+ 23
- 23
source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp View File

@@ -482,17 +482,16 @@ public:
template <class F1, class E1, class F2, class E2>
struct Test5
{
static void test (UnitTest& unitTest)
static void test (UnitTest& unitTest, Random& r)
{
test (unitTest, false);
test (unitTest, true);
test (unitTest, false, r);
test (unitTest, true, r);
}
static void test (UnitTest& unitTest, bool inPlace)
static void test (UnitTest& unitTest, bool inPlace, Random& r)
{
const int numSamples = 2048;
int32 original [numSamples], converted [numSamples], reversed [numSamples];
Random r;
{
AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original);
@@ -549,49 +548,50 @@ public:
template <class F1, class E1, class FormatType>
struct Test3
{
static void test (UnitTest& unitTest)
static void test (UnitTest& unitTest, Random& r)
{
Test5 <F1, E1, FormatType, AudioData::BigEndian>::test (unitTest);
Test5 <F1, E1, FormatType, AudioData::LittleEndian>::test (unitTest);
Test5 <F1, E1, FormatType, AudioData::BigEndian>::test (unitTest, r);
Test5 <F1, E1, FormatType, AudioData::LittleEndian>::test (unitTest, r);
}
};
template <class FormatType, class Endianness>
struct Test2
{
static void test (UnitTest& unitTest)
static void test (UnitTest& unitTest, Random& r)
{
Test3 <FormatType, Endianness, AudioData::Int8>::test (unitTest);
Test3 <FormatType, Endianness, AudioData::UInt8>::test (unitTest);
Test3 <FormatType, Endianness, AudioData::Int16>::test (unitTest);
Test3 <FormatType, Endianness, AudioData::Int24>::test (unitTest);
Test3 <FormatType, Endianness, AudioData::Int32>::test (unitTest);
Test3 <FormatType, Endianness, AudioData::Float32>::test (unitTest);
Test3 <FormatType, Endianness, AudioData::Int8>::test (unitTest, r);
Test3 <FormatType, Endianness, AudioData::UInt8>::test (unitTest, r);
Test3 <FormatType, Endianness, AudioData::Int16>::test (unitTest, r);
Test3 <FormatType, Endianness, AudioData::Int24>::test (unitTest, r);
Test3 <FormatType, Endianness, AudioData::Int32>::test (unitTest, r);
Test3 <FormatType, Endianness, AudioData::Float32>::test (unitTest, r);
}
};
template <class FormatType>
struct Test1
{
static void test (UnitTest& unitTest)
static void test (UnitTest& unitTest, Random& r)
{
Test2 <FormatType, AudioData::BigEndian>::test (unitTest);
Test2 <FormatType, AudioData::LittleEndian>::test (unitTest);
Test2 <FormatType, AudioData::BigEndian>::test (unitTest, r);
Test2 <FormatType, AudioData::LittleEndian>::test (unitTest, r);
}
};
void runTest()
{
Random r = getRandom();
beginTest ("Round-trip conversion: Int8");
Test1 <AudioData::Int8>::test (*this);
Test1 <AudioData::Int8>::test (*this, r);
beginTest ("Round-trip conversion: Int16");
Test1 <AudioData::Int16>::test (*this);
Test1 <AudioData::Int16>::test (*this, r);
beginTest ("Round-trip conversion: Int24");
Test1 <AudioData::Int24>::test (*this);
Test1 <AudioData::Int24>::test (*this, r);
beginTest ("Round-trip conversion: Int32");
Test1 <AudioData::Int32>::test (*this);
Test1 <AudioData::Int32>::test (*this, r);
beginTest ("Round-trip conversion: Float32");
Test1 <AudioData::Float32>::test (*this);
Test1 <AudioData::Float32>::test (*this, r);
}
};


+ 20
- 16
source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp View File

@@ -285,9 +285,7 @@ void AudioSampleBuffer::applyGainRamp (const int channel,
}
}
void AudioSampleBuffer::applyGain (const int startSample,
const int numSamples,
const float gain) noexcept
void AudioSampleBuffer::applyGain (int startSample, int numSamples, float gain) noexcept
{
for (int i = 0; i < numChannels; ++i)
applyGain (i, startSample, numSamples, gain);
@@ -298,10 +296,8 @@ void AudioSampleBuffer::applyGain (const float gain) noexcept
applyGain (0, size, gain);
}
void AudioSampleBuffer::applyGainRamp (const int startSample,
const int numSamples,
const float startGain,
const float endGain) noexcept
void AudioSampleBuffer::applyGainRamp (int startSample, int numSamples,
float startGain, float endGain) noexcept
{
for (int i = 0; i < numChannels; ++i)
applyGainRamp (i, startSample, numSamples, startGain, endGain);
@@ -399,11 +395,9 @@ void AudioSampleBuffer::copyFrom (const int destChannel,
jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
if (numSamples > 0)
{
FloatVectorOperations::copy (channels [destChannel] + destStartSample,
source.channels [sourceChannel] + sourceStartSample,
numSamples);
}
}
void AudioSampleBuffer::copyFrom (const int destChannel,
@@ -416,11 +410,7 @@ void AudioSampleBuffer::copyFrom (const int destChannel,
jassert (source != nullptr);
if (numSamples > 0)
{
FloatVectorOperations::copy (channels [destChannel] + destStartSample,
source,
numSamples);
}
FloatVectorOperations::copy (channels [destChannel] + destStartSample, source, numSamples);
}
void AudioSampleBuffer::copyFrom (const int destChannel,
@@ -482,6 +472,21 @@ void AudioSampleBuffer::copyFromWithRamp (const int destChannel,
}
}
void AudioSampleBuffer::reverse (int channel, int startSample, int numSamples) const noexcept
{
jassert (isPositiveAndBelow (channel, numChannels));
jassert (startSample >= 0 && startSample + numSamples <= size);
std::reverse (channels[channel] + startSample,
channels[channel] + startSample + numSamples);
}
void AudioSampleBuffer::reverse (int startSample, int numSamples) const noexcept
{
for (int i = 0; i < numChannels; ++i)
reverse (i, startSample, numSamples);
}
void AudioSampleBuffer::findMinMax (const int channel,
const int startSample,
int numSamples,
@@ -508,8 +513,7 @@ float AudioSampleBuffer::getMagnitude (const int channel,
return jmax (mn, -mn, mx, -mx);
}
float AudioSampleBuffer::getMagnitude (const int startSample,
const int numSamples) const noexcept
float AudioSampleBuffer::getMagnitude (int startSample, int numSamples) const noexcept
{
float mag = 0.0f;


+ 9
- 9
source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h View File

@@ -107,19 +107,16 @@ public:
//==============================================================================
/** Returns the number of channels of audio data that this buffer contains.
@see getSampleData
*/
int getNumChannels() const noexcept { return numChannels; }
/** Returns the number of samples allocated in each of the buffer's channels.
@see getSampleData
*/
int getNumSamples() const noexcept { return size; }
/** Returns a pointer one of the buffer's channels.
For speed, this doesn't check whether the channel number is out of range,
so be careful when using it!
*/
@@ -409,23 +406,26 @@ public:
float& minVal,
float& maxVal) const noexcept;
/** Finds the highest absolute sample value within a region of a channel.
*/
/** Finds the highest absolute sample value within a region of a channel. */
float getMagnitude (int channel,
int startSample,
int numSamples) const noexcept;
/** Finds the highest absolute sample value within a region on all channels.
*/
/** Finds the highest absolute sample value within a region on all channels. */
float getMagnitude (int startSample,
int numSamples) const noexcept;
/** Returns the root mean squared level for a region of a channel.
*/
/** Returns the root mean squared level for a region of a channel. */
float getRMSLevel (int channel,
int startSample,
int numSamples) const noexcept;
/** Reverses a part of a channel. */
void reverse (int channel, int startSample, int numSamples) const noexcept;
/** Reverses a part of the buffer. */
void reverse (int startSample, int numSamples) const noexcept;
private:
//==============================================================================
int numChannels, size;


+ 0
- 10
source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp View File

@@ -42,13 +42,6 @@ namespace FloatVectorHelpers
return (((pointer_sized_int) p) & 15) == 0;
}
inline static void mmEmpty() noexcept
{
#if ! JUCE_64BIT
_mm_empty();
#endif
}
static inline float findMinimumOrMaximum (const float* src, int num, const bool isMinimum) noexcept
{
#if JUCE_USE_SSE_INTRINSICS
@@ -84,7 +77,6 @@ namespace FloatVectorHelpers
{
float vals[4];
_mm_storeu_ps (vals, val);
FloatVectorHelpers::mmEmpty();
localVal = isMinimum ? jmin (vals[0], vals[1], vals[2], vals[3])
: jmax (vals[0], vals[1], vals[2], vals[3]);
@@ -111,7 +103,6 @@ namespace FloatVectorHelpers
const int numLongOps = num / 4;
#define JUCE_FINISH_SSE_OP(normalOp) \
FloatVectorHelpers::mmEmpty(); \
num &= 3; \
if (num == 0) return; \
} \
@@ -301,7 +292,6 @@ void JUCE_CALLTYPE FloatVectorOperations::findMinAndMax (const float* src, int n
float mns[4], mxs[4];
_mm_storeu_ps (mns, mn);
_mm_storeu_ps (mxs, mx);
FloatVectorHelpers::mmEmpty();
localMin = jmin (mns[0], mns[1], mns[2], mns[3]);
localMax = jmax (mxs[0], mxs[1], mxs[2], mxs[3]);


+ 239
- 0
source/modules/juce_audio_basics/effects/juce_IIRFilterOld.cpp View File

@@ -0,0 +1,239 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
#if JUCE_INTEL
#define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8 || n > 1.0e-8)) n = 0;
#else
#define JUCE_SNAP_TO_ZERO(n)
#endif
//==============================================================================
IIRFilterOld::IIRFilterOld()
: active (false), v1 (0), v2 (0)
{
zeromem (coefficients, sizeof (coefficients));
}
IIRFilterOld::IIRFilterOld (const IIRFilterOld& other)
: active (other.active), v1 (0), v2 (0)
{
const SpinLock::ScopedLockType sl (other.processLock);
memcpy (coefficients, other.coefficients, sizeof (coefficients));
}
IIRFilterOld::~IIRFilterOld()
{
}
//==============================================================================
void IIRFilterOld::reset() noexcept
{
const SpinLock::ScopedLockType sl (processLock);
v1 = v2 = 0;
}
float IIRFilterOld::processSingleSampleRaw (const float in) noexcept
{
float out = coefficients[0] * in + v1;
JUCE_SNAP_TO_ZERO (out);
v1 = coefficients[1] * in - coefficients[3] * out + v2;
v2 = coefficients[2] * in - coefficients[4] * out;
return out;
}
void IIRFilterOld::processSamples (float* const samples,
const int numSamples) noexcept
{
const SpinLock::ScopedLockType sl (processLock);
if (active)
{
const float c0 = coefficients[0];
const float c1 = coefficients[1];
const float c2 = coefficients[2];
const float c3 = coefficients[3];
const float c4 = coefficients[4];
float lv1 = v1, lv2 = v2;
for (int i = 0; i < numSamples; ++i)
{
const float in = samples[i];
const float out = c0 * in + lv1;
samples[i] = out;
lv1 = c1 * in - c3 * out + lv2;
lv2 = c2 * in - c4 * out;
}
JUCE_SNAP_TO_ZERO (lv1); v1 = lv1;
JUCE_SNAP_TO_ZERO (lv2); v2 = lv2;
}
}
//==============================================================================
void IIRFilterOld::makeLowPass (const double sampleRate,
const double frequency) noexcept
{
jassert (sampleRate > 0);
const double n = 1.0 / tan (double_Pi * frequency / sampleRate);
const double nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared);
setCoefficients (c1,
c1 * 2.0f,
c1,
1.0,
c1 * 2.0 * (1.0 - nSquared),
c1 * (1.0 - std::sqrt (2.0) * n + nSquared));
}
void IIRFilterOld::makeHighPass (const double sampleRate,
const double frequency) noexcept
{
const double n = tan (double_Pi * frequency / sampleRate);
const double nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared);
setCoefficients (c1,
c1 * -2.0f,
c1,
1.0,
c1 * 2.0 * (nSquared - 1.0),
c1 * (1.0 - std::sqrt (2.0) * n + nSquared));
}
void IIRFilterOld::makeLowShelf (const double sampleRate,
const double cutOffFrequency,
const double Q,
const float gainFactor) noexcept
{
jassert (sampleRate > 0);
jassert (Q > 0);
const double A = jmax (0.0f, gainFactor);
const double aminus1 = A - 1.0;
const double aplus1 = A + 1.0;
const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate;
const double coso = std::cos (omega);
const double beta = std::sin (omega) * std::sqrt (A) / Q;
const double aminus1TimesCoso = aminus1 * coso;
setCoefficients (A * (aplus1 - aminus1TimesCoso + beta),
A * 2.0 * (aminus1 - aplus1 * coso),
A * (aplus1 - aminus1TimesCoso - beta),
aplus1 + aminus1TimesCoso + beta,
-2.0 * (aminus1 + aplus1 * coso),
aplus1 + aminus1TimesCoso - beta);
}
void IIRFilterOld::makeHighShelf (const double sampleRate,
const double cutOffFrequency,
const double Q,
const float gainFactor) noexcept
{
jassert (sampleRate > 0);
jassert (Q > 0);
const double A = jmax (0.0f, gainFactor);
const double aminus1 = A - 1.0;
const double aplus1 = A + 1.0;
const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate;
const double coso = std::cos (omega);
const double beta = std::sin (omega) * std::sqrt (A) / Q;
const double aminus1TimesCoso = aminus1 * coso;
setCoefficients (A * (aplus1 + aminus1TimesCoso + beta),
A * -2.0 * (aminus1 + aplus1 * coso),
A * (aplus1 + aminus1TimesCoso - beta),
aplus1 - aminus1TimesCoso + beta,
2.0 * (aminus1 - aplus1 * coso),
aplus1 - aminus1TimesCoso - beta);
}
void IIRFilterOld::makeBandPass (const double sampleRate,
const double centreFrequency,
const double Q,
const float gainFactor) noexcept
{
jassert (sampleRate > 0);
jassert (Q > 0);
const double A = jmax (0.0f, gainFactor);
const double omega = (double_Pi * 2.0 * jmax (centreFrequency, 2.0)) / sampleRate;
const double alpha = 0.5 * std::sin (omega) / Q;
const double c2 = -2.0 * std::cos (omega);
const double alphaTimesA = alpha * A;
const double alphaOverA = alpha / A;
setCoefficients (1.0 + alphaTimesA,
c2,
1.0 - alphaTimesA,
1.0 + alphaOverA,
c2,
1.0 - alphaOverA);
}
void IIRFilterOld::makeInactive() noexcept
{
const SpinLock::ScopedLockType sl (processLock);
active = false;
}
//==============================================================================
void IIRFilterOld::copyCoefficientsFrom (const IIRFilterOld& other) noexcept
{
const SpinLock::ScopedLockType sl (processLock);
memcpy (coefficients, other.coefficients, sizeof (coefficients));
active = other.active;
}
//==============================================================================
void IIRFilterOld::setCoefficients (double c1, double c2, double c3,
double c4, double c5, double c6) noexcept
{
const double a = 1.0 / c4;
c1 *= a;
c2 *= a;
c3 *= a;
c5 *= a;
c6 *= a;
const SpinLock::ScopedLockType sl (processLock);
coefficients[0] = (float) c1;
coefficients[1] = (float) c2;
coefficients[2] = (float) c3;
coefficients[3] = (float) c5;
coefficients[4] = (float) c6;
active = true;
}
#undef JUCE_SNAP_TO_ZERO

+ 148
- 0
source/modules/juce_audio_basics/effects/juce_IIRFilterOld.h View File

@@ -0,0 +1,148 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
#ifndef __JUCE_IIRFILTER_OLD_JUCEHEADER__
#define __JUCE_IIRFILTER_OLD_JUCEHEADER__
//==============================================================================
/**
An IIR filter that can perform low, high, or band-pass filtering on an
audio signal.
@see IIRFilterAudioSource
*/
class JUCE_API IIRFilterOld
{
public:
//==============================================================================
/** Creates a filter.
Initially the filter is inactive, so will have no effect on samples that
you process with it. Use the appropriate method to turn it into the type
of filter needed.
*/
IIRFilterOld();
/** Creates a copy of another filter. */
IIRFilterOld (const IIRFilterOld& other);
/** Destructor. */
~IIRFilterOld();
//==============================================================================
/** Resets the filter's processing pipeline, ready to start a new stream of data.
Note that this clears the processing state, but the type of filter and
its coefficients aren't changed. To put a filter into an inactive state, use
the makeInactive() method.
*/
void reset() noexcept;
/** Performs the filter operation on the given set of samples.
*/
void processSamples (float* samples,
int numSamples) noexcept;
/** Processes a single sample, without any locking or checking.
Use this if you need fast processing of a single value, but be aware that
this isn't thread-safe in the way that processSamples() is.
*/
float processSingleSampleRaw (float sample) noexcept;
//==============================================================================
/** Sets the filter up to act as a low-pass filter.
*/
void makeLowPass (double sampleRate,
double frequency) noexcept;
/** Sets the filter up to act as a high-pass filter.
*/
void makeHighPass (double sampleRate,
double frequency) noexcept;
//==============================================================================
/** Sets the filter up to act as a low-pass shelf filter with variable Q and gain.
The gain is a scale factor that the low frequencies are multiplied by, so values
greater than 1.0 will boost the low frequencies, values less than 1.0 will
attenuate them.
*/
void makeLowShelf (double sampleRate,
double cutOffFrequency,
double Q,
float gainFactor) noexcept;
/** Sets the filter up to act as a high-pass shelf filter with variable Q and gain.
The gain is a scale factor that the high frequencies are multiplied by, so values
greater than 1.0 will boost the high frequencies, values less than 1.0 will
attenuate them.
*/
void makeHighShelf (double sampleRate,
double cutOffFrequency,
double Q,
float gainFactor) noexcept;
/** Sets the filter up to act as a band pass filter centred around a
frequency, with a variable Q and gain.
The gain is a scale factor that the centre frequencies are multiplied by, so
values greater than 1.0 will boost the centre frequencies, values less than
1.0 will attenuate them.
*/
void makeBandPass (double sampleRate,
double centreFrequency,
double Q,
float gainFactor) noexcept;
/** Clears the filter's coefficients so that it becomes inactive.
*/
void makeInactive() noexcept;
//==============================================================================
/** Makes this filter duplicate the set-up of another one.
*/
void copyCoefficientsFrom (const IIRFilterOld& other) noexcept;
protected:
//==============================================================================
SpinLock processLock;
void setCoefficients (double c1, double c2, double c3,
double c4, double c5, double c6) noexcept;
bool active;
float coefficients[5];
float v1, v2;
// (use the copyCoefficientsFrom() method instead of this operator)
IIRFilterOld& operator= (const IIRFilterOld&);
JUCE_LEAK_DETECTOR (IIRFilterOld)
};
#endif // __JUCE_IIRFILTER_OLD_JUCEHEADER__

+ 1
- 0
source/modules/juce_audio_basics/juce_audio_basics.cpp View File

@@ -65,6 +65,7 @@ namespace juce
#include "buffers/juce_AudioSampleBuffer.cpp"
#include "buffers/juce_FloatVectorOperations.cpp"
#include "effects/juce_IIRFilter.cpp"
#include "effects/juce_IIRFilterOld.cpp"
#include "effects/juce_LagrangeInterpolator.cpp"
#include "midi/juce_MidiBuffer.cpp"
#include "midi/juce_MidiFile.cpp"


+ 1
- 0
source/modules/juce_audio_basics/juce_audio_basics.h View File

@@ -36,6 +36,7 @@ namespace juce
#include "buffers/juce_FloatVectorOperations.h"
#include "effects/juce_Decibels.h"
#include "effects/juce_IIRFilter.h"
#include "effects/juce_IIRFilterOld.h"
#include "effects/juce_LagrangeInterpolator.h"
#include "effects/juce_Reverb.h"
#include "midi/juce_MidiMessage.h"


+ 1
- 1
source/modules/juce_audio_basics/juce_module_info View File

@@ -1,7 +1,7 @@
{
"id": "juce_audio_basics",
"name": "JUCE audio and midi data classes",
"version": "2.1.2",
"version": "2.1.3",
"description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc",
"website": "http://www.juce.com/juce",
"license": "GPL/Commercial",


+ 2
- 4
source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp View File

@@ -240,9 +240,8 @@ uint8* MidiBuffer::findEventAfter (uint8* d, const int samplePosition) const noe
}
//==============================================================================
MidiBuffer::Iterator::Iterator (const MidiBuffer& buffer_) noexcept
: buffer (buffer_),
data (buffer_.getData())
MidiBuffer::Iterator::Iterator (const MidiBuffer& b) noexcept
: buffer (b), data (b.getData())
{
}
@@ -250,7 +249,6 @@ MidiBuffer::Iterator::~Iterator() noexcept
{
}
//==============================================================================
void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) noexcept
{
data = buffer.getData();


+ 3
- 3
source/modules/juce_audio_basics/midi/juce_MidiBuffer.h View File

@@ -51,10 +51,10 @@ public:
explicit MidiBuffer (const MidiMessage& message) noexcept;
/** Creates a copy of another MidiBuffer. */
MidiBuffer (const MidiBuffer& other) noexcept;
MidiBuffer (const MidiBuffer&) noexcept;
/** Makes a copy of another MidiBuffer. */
MidiBuffer& operator= (const MidiBuffer& other) noexcept;
MidiBuffer& operator= (const MidiBuffer&) noexcept;
/** Destructor */
~MidiBuffer();
@@ -176,7 +176,7 @@ public:
public:
//==============================================================================
/** Creates an Iterator for this MidiBuffer. */
Iterator (const MidiBuffer& buffer) noexcept;
Iterator (const MidiBuffer&) noexcept;
/** Destructor. */
~Iterator() noexcept;


+ 29
- 29
source/modules/juce_audio_basics/midi/juce_MidiFile.cpp View File

@@ -146,6 +146,26 @@ namespace MidiFileHelpers
return 0;
}
};
template <typename MethodType>
static void findAllMatchingEvents (const OwnedArray<MidiMessageSequence>& tracks,
MidiMessageSequence& results,
MethodType method)
{
for (int i = 0; i < tracks.size(); ++i)
{
const MidiMessageSequence& track = *tracks.getUnchecked(i);
const int numEvents = track.getNumEvents();
for (int j = 0; j < numEvents; ++j)
{
const MidiMessage& m = track.getEventPointer(j)->message;
if ((m.*method)())
results.addEvent (m);
}
}
}
}
//==============================================================================
@@ -197,36 +217,19 @@ void MidiFile::setSmpteTimeFormat (const int framesPerSecond,
}
//==============================================================================
void MidiFile::findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const
void MidiFile::findAllTempoEvents (MidiMessageSequence& results) const
{
for (int i = tracks.size(); --i >= 0;)
{
const int numEvents = tracks.getUnchecked(i)->getNumEvents();
for (int j = 0; j < numEvents; ++j)
{
const MidiMessage& m = tracks.getUnchecked(i)->getEventPointer (j)->message;
if (m.isTempoMetaEvent())
tempoChangeEvents.addEvent (m);
}
}
MidiFileHelpers::findAllMatchingEvents (tracks, results, &MidiMessage::isTempoMetaEvent);
}
void MidiFile::findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const
void MidiFile::findAllTimeSigEvents (MidiMessageSequence& results) const
{
for (int i = tracks.size(); --i >= 0;)
{
const int numEvents = tracks.getUnchecked(i)->getNumEvents();
for (int j = 0; j < numEvents; ++j)
{
const MidiMessage& m = tracks.getUnchecked(i)->getEventPointer (j)->message;
MidiFileHelpers::findAllMatchingEvents (tracks, results, &MidiMessage::isTimeSignatureMetaEvent);
}
if (m.isTimeSignatureMetaEvent())
timeSigEvents.addEvent (m);
}
}
void MidiFile::findAllKeySigEvents (MidiMessageSequence& results) const
{
MidiFileHelpers::findAllMatchingEvents (tracks, results, &MidiMessage::isKeySignatureMetaEvent);
}
double MidiFile::getLastTimestamp() const
@@ -340,10 +343,7 @@ void MidiFile::convertTimestampTicksToSeconds()
for (int j = ms.getNumEvents(); --j >= 0;)
{
MidiMessage& m = ms.getEventPointer(j)->message;
m.setTimeStamp (MidiFileHelpers::convertTicksToSeconds (m.getTimeStamp(),
tempoEvents,
timeFormat));
m.setTimeStamp (MidiFileHelpers::convertTicksToSeconds (m.getTimeStamp(), tempoEvents, timeFormat));
}
}
}


+ 8
- 14
source/modules/juce_audio_basics/midi/juce_MidiFile.h View File

@@ -52,28 +52,23 @@ public:
//==============================================================================
/** Returns the number of tracks in the file.
@see getTrack, addTrack
*/
int getNumTracks() const noexcept;
/** Returns a pointer to one of the tracks in the file.
@returns a pointer to the track, or nullptr if the index is out-of-range
@see getNumTracks, addTrack
*/
const MidiMessageSequence* getTrack (int index) const noexcept;
/** Adds a midi track to the file.
This will make its own internal copy of the sequence that is passed-in.
@see getNumTracks, getTrack
*/
void addTrack (const MidiMessageSequence& trackSequence);
/** Removes all midi tracks from the file.
@see getNumTracks
*/
void clear();
@@ -120,23 +115,23 @@ public:
//==============================================================================
/** Makes a list of all the tempo-change meta-events from all tracks in the midi file.
Useful for finding the positions of all the tempo changes in a file.
@param tempoChangeEvents a list to which all the events will be added
*/
void findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const;
/** Makes a list of all the time-signature meta-events from all tracks in the midi file.
Useful for finding the positions of all the tempo changes in a file.
@param timeSigEvents a list to which all the events will be added
*/
void findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const;
/** Returns the latest timestamp in any of the tracks.
/** Makes a list of all the time-signature meta-events from all tracks in the midi file.
@param keySigEvents a list to which all the events will be added
*/
void findAllKeySigEvents (MidiMessageSequence& keySigEvents) const;
/** Returns the latest timestamp in any of the tracks.
(Useful for finding the length of the file).
*/
double getLastTimestamp() const;
@@ -156,7 +151,6 @@ public:
bool readFrom (InputStream& sourceStream);
/** Writes the midi tracks as a standard midi file.
@returns true if the operation succeeded.
*/
bool writeTo (OutputStream& destStream);
@@ -171,11 +165,11 @@ public:
private:
//==============================================================================
OwnedArray <MidiMessageSequence> tracks;
OwnedArray<MidiMessageSequence> tracks;
short timeFormat;
void readNextTrack (const uint8* data, int size);
void writeTrack (OutputStream& mainOut, int trackNum);
void readNextTrack (const uint8*, int size);
void writeTrack (OutputStream&, int trackNum);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiFile)
};


+ 6
- 1
source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp View File

@@ -797,7 +797,12 @@ bool MidiMessage::isKeySignatureMetaEvent() const noexcept
int MidiMessage::getKeySignatureNumberOfSharpsOrFlats() const noexcept
{
return (int) *getMetaEventData();
return (int) getMetaEventData()[0];
}
bool MidiMessage::isKeySignatureMajorKey() const noexcept
{
return getMetaEventData()[1] == 0;
}
MidiMessage MidiMessage::endOfTrack() noexcept


+ 12
- 23
source/modules/juce_audio_basics/midi/juce_MidiMessage.h View File

@@ -112,13 +112,11 @@ public:
//==============================================================================
/** Returns a pointer to the raw midi data.
@see getRawDataSize
*/
const uint8* getRawData() const noexcept { return data; }
/** Returns the number of bytes of data in the message.
@see getRawData
*/
int getRawDataSize() const noexcept { return size; }
@@ -143,15 +141,12 @@ public:
double getTimeStamp() const noexcept { return timeStamp; }
/** Changes the message's associated timestamp.
The units for the timestamp will be application-specific - see the notes for getTimeStamp().
@see addToTimeStamp, getTimeStamp
*/
void setTimeStamp (double newTimestamp) noexcept { timeStamp = newTimestamp; }
/** Adds a value to the message's timestamp.
The units for the timestamp will be application-specific.
*/
void addToTimeStamp (double delta) noexcept { timeStamp += delta; }
@@ -569,7 +564,6 @@ public:
//==============================================================================
/** Returns true if this is a 'tempo' meta-event.
@see getTempoMetaEventTickLength, getTempoSecondsPerQuarterNote
*/
bool isTempoMetaEvent() const noexcept;
@@ -583,49 +577,51 @@ public:
double getTempoMetaEventTickLength (short timeFormat) const noexcept;
/** Calculates the seconds-per-quarter-note from a tempo meta-event.
@see isTempoMetaEvent, getTempoMetaEventTickLength
*/
double getTempoSecondsPerQuarterNote() const noexcept;
/** Creates a tempo meta-event.
@see isTempoMetaEvent
*/
static MidiMessage tempoMetaEvent (int microsecondsPerQuarterNote) noexcept;
//==============================================================================
/** Returns true if this is a 'time-signature' meta-event.
@see getTimeSignatureInfo
*/
bool isTimeSignatureMetaEvent() const noexcept;
/** Returns the time-signature values from a time-signature meta-event.
@see isTimeSignatureMetaEvent
*/
void getTimeSignatureInfo (int& numerator, int& denominator) const noexcept;
/** Creates a time-signature meta-event.
@see isTimeSignatureMetaEvent
*/
static MidiMessage timeSignatureMetaEvent (int numerator, int denominator);
//==============================================================================
/** Returns true if this is a 'key-signature' meta-event.
@see getKeySignatureNumberOfSharpsOrFlats
@see getKeySignatureNumberOfSharpsOrFlats, isKeySignatureMajorKey
*/
bool isKeySignatureMetaEvent() const noexcept;
/** Returns the key from a key-signature meta-event.
@see isKeySignatureMetaEvent
This method must only be called if isKeySignatureMetaEvent() is true.
A positive number here indicates the number of sharps in the key signature,
and a negative number indicates a number of flats. So e.g. 3 = F# + C# + G#,
-2 = Bb + Eb
@see isKeySignatureMetaEvent, isKeySignatureMajorKey
*/
int getKeySignatureNumberOfSharpsOrFlats() const noexcept;
/** Returns true if this key-signature event is major, or false if it's minor.
This method must only be called if isKeySignatureMetaEvent() is true.
*/
bool isKeySignatureMajorKey() const noexcept;
//==============================================================================
/** Returns true if this is a 'channel' meta-event.
@@ -807,14 +803,11 @@ public:
*/
MidiMachineControlCommand getMidiMachineControlCommand() const noexcept;
/** Creates an MMC message.
*/
/** Creates an MMC message. */
static MidiMessage midiMachineControlCommand (MidiMachineControlCommand command);
/** Checks whether this is an MMC "goto" message.
If it is, the parameters passed-in are set to the time that the message contains.
@see midiMachineControlGoto
*/
bool isMidiMachineControlGoto (int& hours,
@@ -823,9 +816,7 @@ public:
int& frames) const noexcept;
/** Creates an MMC "goto" message.
This messages tells the device to go to a specific frame.
@see isMidiMachineControlGoto
*/
static MidiMessage midiMachineControlGoto (int hours,
@@ -835,14 +826,12 @@ public:
//==============================================================================
/** Creates a master-volume change message.
@param volume the volume, 0 to 1.0
*/
static MidiMessage masterVolume (float volume);
//==============================================================================
/** Creates a system-exclusive message.
The data passed in is wrapped with header and tail bytes of 0xf0 and 0xf7.
*/
static MidiMessage createSysExMessage (const void* sysexData,


+ 2
- 3
source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp View File

@@ -284,7 +284,7 @@ void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumbe
{
bool doneProg = false;
bool donePitchWheel = false;
Array <int> doneControllers;
Array<int> doneControllers;
doneControllers.ensureStorageAllocated (32);
for (int i = list.size(); --i >= 0;)
@@ -324,8 +324,7 @@ void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumbe
//==============================================================================
MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm)
: message (mm),
noteOffObject (nullptr)
: message (mm), noteOffObject (nullptr)
{
}


+ 17
- 17
source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp View File

@@ -22,16 +22,16 @@
==============================================================================
*/
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* source_,
TimeSliceThread& backgroundThread_,
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s,
TimeSliceThread& thread,
const bool deleteSourceWhenDeleted,
const int numberOfSamplesToBuffer_,
const int numberOfChannels_)
: source (source_, deleteSourceWhenDeleted),
backgroundThread (backgroundThread_),
numberOfSamplesToBuffer (jmax (1024, numberOfSamplesToBuffer_)),
numberOfChannels (numberOfChannels_),
buffer (numberOfChannels_, 0),
const int bufferSizeSamples,
const int numChannels)
: source (s, deleteSourceWhenDeleted),
backgroundThread (thread),
numberOfSamplesToBuffer (jmax (1024, bufferSizeSamples)),
numberOfChannels (numChannels),
buffer (numChannels, 0),
bufferValidStart (0),
bufferValidEnd (0),
nextPlayPos (0),
@@ -39,10 +39,10 @@ BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* source_,
wasSourceLooping (false),
isPrepared (false)
{
jassert (source_ != nullptr);
jassert (source != nullptr);
jassert (numberOfSamplesToBuffer_ > 1024); // not much point using this class if you're
// not using a larger buffer..
jassert (numberOfSamplesToBuffer > 1024); // not much point using this class if you're
// not using a larger buffer..
}
BufferingAudioSource::~BufferingAudioSource()
@@ -51,20 +51,20 @@ BufferingAudioSource::~BufferingAudioSource()
}
//==============================================================================
void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate_)
void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double newSampleRate)
{
const int bufferSizeNeeded = jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer);
if (sampleRate_ != sampleRate
if (newSampleRate != sampleRate
|| bufferSizeNeeded != buffer.getNumSamples()
|| ! isPrepared)
{
backgroundThread.removeTimeSliceClient (this);
isPrepared = true;
sampleRate = sampleRate_;
sampleRate = newSampleRate;
source->prepareToPlay (samplesPerBlockExpected, sampleRate_);
source->prepareToPlay (samplesPerBlockExpected, newSampleRate);
buffer.setSize (numberOfChannels, bufferSizeNeeded);
buffer.clear();
@@ -74,7 +74,7 @@ void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sa
backgroundThread.addTimeSliceClient (this);
while (bufferValidEnd - bufferValidStart < jmin (((int) sampleRate_) / 4,
while (bufferValidEnd - bufferValidStart < jmin (((int) newSampleRate) / 4,
buffer.getNumSamples() / 2))
{
backgroundThread.moveToFrontOfQueue (this);


+ 2
- 3
source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp View File

@@ -48,12 +48,11 @@ void ToneGeneratorAudioSource::setFrequency (const double newFrequencyHz)
}
//==============================================================================
void ToneGeneratorAudioSource::prepareToPlay (int /*samplesPerBlockExpected*/,
double sampleRate_)
void ToneGeneratorAudioSource::prepareToPlay (int /*samplesPerBlockExpected*/, double rate)
{
currentPhase = 0.0;
phasePerSample = 0.0;
sampleRate = sampleRate_;
sampleRate = rate;
}
void ToneGeneratorAudioSource::releaseResources()


+ 15
- 25
source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp View File

@@ -22,13 +22,8 @@
==============================================================================
*/
SynthesiserSound::SynthesiserSound()
{
}
SynthesiserSound::~SynthesiserSound()
{
}
SynthesiserSound::SynthesiserSound() {}
SynthesiserSound::~SynthesiserSound() {}
//==============================================================================
SynthesiserVoice::SynthesiserVoice()
@@ -118,9 +113,9 @@ void Synthesiser::removeSound (const int index)
sounds.remove (index);
}
void Synthesiser::setNoteStealingEnabled (const bool shouldStealNotes_)
void Synthesiser::setNoteStealingEnabled (const bool shouldSteal)
{
shouldStealNotes = shouldStealNotes_;
shouldStealNotes = shouldSteal;
}
//==============================================================================
@@ -139,10 +134,8 @@ void Synthesiser::setCurrentPlaybackSampleRate (const double newRate)
}
}
void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer,
const MidiBuffer& midiData,
int startSample,
int numSamples)
void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBuffer& midiData,
int startSample, int numSamples)
{
// must set the sample rate before using this!
jassert (sampleRate != 0);
@@ -180,15 +173,11 @@ void Synthesiser::handleMidiEvent (const MidiMessage& m)
{
if (m.isNoteOn())
{
noteOn (m.getChannel(),
m.getNoteNumber(),
m.getFloatVelocity());
noteOn (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity());
}
else if (m.isNoteOff())
{
noteOff (m.getChannel(),
m.getNoteNumber(),
true);
noteOff (m.getChannel(), m.getNoteNumber(), true);
}
else if (m.isAllNotesOff() || m.isAllSoundOff())
{
@@ -204,9 +193,7 @@ void Synthesiser::handleMidiEvent (const MidiMessage& m)
}
else if (m.isController())
{
handleController (m.getChannel(),
m.getControllerNumber(),
m.getControllerValue());
handleController (m.getChannel(), m.getControllerNumber(), m.getControllerValue());
}
}
@@ -406,9 +393,12 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
const ScopedLock sl (lock);
for (int i = voices.size(); --i >= 0;)
if (voices.getUnchecked (i)->getCurrentlyPlayingNote() < 0
&& voices.getUnchecked (i)->canPlaySound (soundToPlay))
return voices.getUnchecked (i);
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->getCurrentlyPlayingNote() < 0 && voice->canPlaySound (soundToPlay))
return voice;
}
if (stealIfNoneAvailable)
{


+ 25
- 27
source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h View File

@@ -64,9 +64,8 @@ public:
*/
virtual bool appliesToChannel (const int midiChannel) = 0;
/**
*/
typedef ReferenceCountedObjectPtr <SynthesiserSound> Ptr;
/** The class is reference-counted, so this is a handy pointer class for it. */
typedef ReferenceCountedObjectPtr<SynthesiserSound> Ptr;
private:
@@ -96,16 +95,14 @@ public:
//==============================================================================
/** Returns the midi note that this voice is currently playing.
Returns a value less than 0 if no note is playing.
*/
int getCurrentlyPlayingNote() const { return currentlyPlayingNote; }
int getCurrentlyPlayingNote() const noexcept { return currentlyPlayingNote; }
/** Returns the sound that this voice is currently playing.
Returns nullptr if it's not playing.
*/
SynthesiserSound::Ptr getCurrentlyPlayingSound() const { return currentlyPlayingSound; }
SynthesiserSound::Ptr getCurrentlyPlayingSound() const noexcept { return currentlyPlayingSound; }
/** Must return true if this voice object is capable of playing the given sound.
@@ -116,16 +113,16 @@ public:
of voice and sound, or it might check the type of the sound object passed-in and
see if it's one that it understands.
*/
virtual bool canPlaySound (SynthesiserSound* sound) = 0;
virtual bool canPlaySound (SynthesiserSound*) = 0;
/** Called to start a new note.
This will be called during the rendering callback, so must be fast and thread-safe.
*/
virtual void startNote (const int midiNoteNumber,
const float velocity,
virtual void startNote (int midiNoteNumber,
float velocity,
SynthesiserSound* sound,
const int currentPitchWheelPosition) = 0;
int currentPitchWheelPosition) = 0;
/** Called to stop a note.
@@ -140,20 +137,17 @@ public:
finishes playing (during the rendering callback), it must make sure that it calls
clearCurrentNote().
*/
virtual void stopNote (const bool allowTailOff) = 0;
virtual void stopNote (bool allowTailOff) = 0;
/** Called to let the voice know that the pitch wheel has been moved.
This will be called during the rendering callback, so must be fast and thread-safe.
*/
virtual void pitchWheelMoved (const int newValue) = 0;
virtual void pitchWheelMoved (int newValue) = 0;
/** Called to let the voice know that a midi controller has been moved.
This will be called during the rendering callback, so must be fast and thread-safe.
*/
virtual void controllerMoved (const int controllerNumber,
const int newValue) = 0;
virtual void controllerMoved (int controllerNumber, int newValue) = 0;
//==============================================================================
/** Renders the next block of data for this voice.
@@ -273,7 +267,7 @@ public:
void clearVoices();
/** Returns the number of voices that have been added. */
int getNumVoices() const { return voices.size(); }
int getNumVoices() const noexcept { return voices.size(); }
/** Returns one of the voices that have been added. */
SynthesiserVoice* getVoice (int index) const;
@@ -296,10 +290,10 @@ public:
void clearSounds();
/** Returns the number of sounds that have been added to the synth. */
int getNumSounds() const { return sounds.size(); }
int getNumSounds() const noexcept { return sounds.size(); }
/** Returns one of the sounds. */
SynthesiserSound* getSound (int index) const { return sounds [index]; }
SynthesiserSound* getSound (int index) const noexcept { return sounds [index]; }
/** Adds a new sound to the synthesiser.
@@ -323,7 +317,7 @@ public:
/** Returns true if note-stealing is enabled.
@see setNoteStealingEnabled
*/
bool isNoteStealingEnabled() const { return shouldStealNotes; }
bool isNoteStealingEnabled() const noexcept { return shouldStealNotes; }
//==============================================================================
/** Triggers a note-on event.
@@ -376,7 +370,7 @@ public:
virtual void allNotesOff (int midiChannel,
bool allowTailOff);
/** Sends a pitch-wheel message.
/** Sends a pitch-wheel message to any active voices.
This will send a pitch-wheel message to any voices that are playing sounds on
the given midi channel.
@@ -390,7 +384,7 @@ public:
virtual void handlePitchWheel (int midiChannel,
int wheelValue);
/** Sends a midi controller message.
/** Sends a midi controller message to any active voices.
This will send a midi controller message to any voices that are playing sounds on
the given midi channel.
@@ -406,13 +400,17 @@ public:
int controllerNumber,
int controllerValue);
/** Handles a sustain pedal event. */
virtual void handleSustainPedal (int midiChannel, bool isDown);
/** Handles a sostenuto pedal event. */
virtual void handleSostenutoPedal (int midiChannel, bool isDown);
/** Can be overridden to handle soft pedal events. */
virtual void handleSoftPedal (int midiChannel, bool isDown);
//==============================================================================
/** Tells the synthesiser what the sample rate is for the audio it's being used to
render.
/** Tells the synthesiser what the sample rate is for the audio it's being used to render.
This value is propagated to the voices so that they can use it to render the correct
pitches.
@@ -441,8 +439,8 @@ protected:
/** This is used to control access to the rendering callback and the note trigger methods. */
CriticalSection lock;
OwnedArray <SynthesiserVoice> voices;
ReferenceCountedArray <SynthesiserSound> sounds;
OwnedArray<SynthesiserVoice> voices;
ReferenceCountedArray<SynthesiserSound> sounds;
/** The last pitch-wheel values for each midi channel. */
int lastPitchWheelValues [16];


+ 4
- 17
source/modules/juce_core/AppConfig.h View File

@@ -33,11 +33,7 @@
@see jassert, jassertfalse, Logger
*/
#if DEBUG
#define JUCE_LOG_ASSERTIONS 1
#else
#define JUCE_LOG_ASSERTIONS 0
#endif
#define JUCE_LOG_ASSERTIONS 1
//=============================================================================
/** Config: JUCE_CHECK_MEMORY_LEAKS
@@ -45,11 +41,7 @@
Enables a memory-leak check for certain objects when the app terminates. See the LeakedObjectDetector
class and the JUCE_LEAK_DETECTOR macro for more details about enabling leak checking for specific classes.
*/
//#if DEBUG
#define JUCE_CHECK_MEMORY_LEAKS 1
//#else
// #define JUCE_CHECK_MEMORY_LEAKS 0
//#endif
//=============================================================================
/** Config: JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
@@ -59,7 +51,7 @@
*/
#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0
/* Config: JUCE_INCLUDE_ZLIB_CODE
/** Config: JUCE_INCLUDE_ZLIB_CODE
This can be used to disable Juce's embedded 3rd-party zlib code.
You might need to tweak this if you're linking to an external zlib library in your app,
but for normal apps, this option should be left alone.
@@ -68,17 +60,12 @@
specify the path where your zlib headers live.
*/
#define JUCE_INCLUDE_ZLIB_CODE 1
//#define JUCE_ZLIB_INCLUDE_PATH <zlib.h>
/* Config: JUCE_CATCH_UNHANDLED_EXCEPTIONS
If enabled, this will add some exception-catching code to forward unhandled exceptions
to your JUCEApplication::unhandledException() callback.
to your JUCEApplicationBase::unhandledException() callback.
*/
#if DEBUG
#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
#else
#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0
#endif
#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1


+ 7
- 6
source/modules/juce_core/containers/juce_AbstractFifo.cpp View File

@@ -141,8 +141,8 @@ public:
class WriteThread : public Thread
{
public:
WriteThread (AbstractFifo& fifo_, int* buffer_)
: Thread ("fifo writer"), fifo (fifo_), buffer (buffer_)
WriteThread (AbstractFifo& f, int* b, Random rng)
: Thread ("fifo writer"), fifo (f), buffer (b), random (rng)
{
startThread();
}
@@ -155,11 +155,10 @@ public:
void run()
{
int n = 0;
Random r;
while (! threadShouldExit())
{
int num = r.nextInt (2000) + 1;
int num = random.nextInt (2000) + 1;
int start1, size1, start2, size2;
fifo.prepareToWrite (num, start1, size1, start2, size2);
@@ -181,6 +180,7 @@ public:
private:
AbstractFifo& fifo;
int* buffer;
Random random;
};
void runTest()
@@ -190,10 +190,11 @@ public:
int buffer [5000];
AbstractFifo fifo (numElementsInArray (buffer));
WriteThread writer (fifo, buffer);
WriteThread writer (fifo, buffer, getRandom());
int n = 0;
Random r;
Random r = getRandom();
r.combineSeed (12345);
for (int count = 100000; --count >= 0;)
{


+ 25
- 7
source/modules/juce_core/containers/juce_Array.h View File

@@ -546,11 +546,13 @@ public:
/** Adds elements from an array to the end of this array.
@param elementsToAdd the array of elements to add
@param elementsToAdd an array of some kind of object from which elements
can be constructed.
@param numElementsToAdd how many elements are in this other array
@see add
*/
void addArray (const ElementType* elementsToAdd, int numElementsToAdd)
template <typename Type>
void addArray (const Type* elementsToAdd, int numElementsToAdd)
{
const ScopedLockType lock (getLock());
@@ -566,6 +568,22 @@ public:
}
}
/** Adds elements from a null-terminated array of pointers to the end of this array.
@param elementsToAdd an array of pointers to some kind of object from which elements
can be constructed. This array must be terminated by a nullptr
@see addArray
*/
template <typename Type>
void addNullTerminatedArray (const Type* const* elementsToAdd)
{
int num = 0;
for (const Type* const* e = elementsToAdd; *e != nullptr; ++e)
++num;
addArray (elementsToAdd, num);
}
/** This swaps the contents of this array with those of another array.
If you need to exchange two arrays, this is vastly quicker than using copy-by-value
@@ -715,7 +733,7 @@ public:
@param indexToRemove the index of the element to remove
@returns the element that has been removed
@see removeValue, removeRange
@see removeFirstMatchingValue, removeAllInstancesOf, removeRange
*/
ElementType remove (const int indexToRemove)
{
@@ -782,7 +800,7 @@ public:
@param startIndex the index of the first element to remove
@param numberToRemove how many elements should be removed
@see remove, removeValue
@see remove, removeFirstMatchingValue, removeAllInstancesOf
*/
void removeRange (int startIndex, int numberToRemove)
{
@@ -810,7 +828,7 @@ public:
/** Removes the last n elements from the array.
@param howManyToRemove how many elements to remove from the end of the array
@see remove, removeValue, removeRange
@see remove, removeFirstMatchingValue, removeAllInstancesOf, removeRange
*/
void removeLast (int howManyToRemove = 1)
{
@@ -829,7 +847,7 @@ public:
/** Removes any elements which are also in another array.
@param otherArray the other array in which to look for elements to remove
@see removeValuesNotIn, remove, removeValue, removeRange
@see removeValuesNotIn, remove, removeFirstMatchingValue, removeAllInstancesOf, removeRange
*/
template <class OtherArrayType>
void removeValuesIn (const OtherArrayType& otherArray)
@@ -857,7 +875,7 @@ public:
Only elements which occur in this other array will be retained.
@param otherArray the array in which to look for elements NOT to remove
@see removeValuesIn, remove, removeValue, removeRange
@see removeValuesIn, remove, removeFirstMatchingValue, removeAllInstancesOf, removeRange
*/
template <class OtherArrayType>
void removeValuesNotIn (const OtherArrayType& otherArray)


+ 7
- 11
source/modules/juce_core/containers/juce_PropertySet.cpp View File

@@ -65,8 +65,7 @@ void PropertySet::clear()
}
}
String PropertySet::getValue (const String& keyName,
const String& defaultValue) const noexcept
String PropertySet::getValue (StringRef keyName, const String& defaultValue) const noexcept
{
const ScopedLock sl (lock);
@@ -79,8 +78,7 @@ String PropertySet::getValue (const String& keyName,
: defaultValue;
}
int PropertySet::getIntValue (const String& keyName,
const int defaultValue) const noexcept
int PropertySet::getIntValue (StringRef keyName, const int defaultValue) const noexcept
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
@@ -92,8 +90,7 @@ int PropertySet::getIntValue (const String& keyName,
: defaultValue;
}
double PropertySet::getDoubleValue (const String& keyName,
const double defaultValue) const noexcept
double PropertySet::getDoubleValue (StringRef keyName, const double defaultValue) const noexcept
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
@@ -105,8 +102,7 @@ double PropertySet::getDoubleValue (const String& keyName,
: defaultValue;
}
bool PropertySet::getBoolValue (const String& keyName,
const bool defaultValue) const noexcept
bool PropertySet::getBoolValue (StringRef keyName, const bool defaultValue) const noexcept
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
@@ -118,7 +114,7 @@ bool PropertySet::getBoolValue (const String& keyName,
: defaultValue;
}
XmlElement* PropertySet::getXmlValue (const String& keyName) const
XmlElement* PropertySet::getXmlValue (StringRef keyName) const
{
return XmlDocument::parse (getValue (keyName));
}
@@ -142,7 +138,7 @@ void PropertySet::setValue (const String& keyName, const var& v)
}
}
void PropertySet::removeValue (const String& keyName)
void PropertySet::removeValue (StringRef keyName)
{
if (keyName.isNotEmpty())
{
@@ -163,7 +159,7 @@ void PropertySet::setValue (const String& keyName, const XmlElement* const xml)
: var (xml->createDocument (String::empty, true)));
}
bool PropertySet::containsKey (const String& keyName) const noexcept
bool PropertySet::containsKey (StringRef keyName) const noexcept
{
const ScopedLock sl (lock);
return properties.getAllKeys().contains (keyName, ignoreCaseOfKeys);


+ 7
- 11
source/modules/juce_core/containers/juce_PropertySet.h View File

@@ -69,8 +69,7 @@ public:
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
String getValue (const String& keyName,
const String& defaultReturnValue = String::empty) const noexcept;
String getValue (StringRef keyName, const String& defaultReturnValue = String::empty) const noexcept;
/** Returns one of the properties as an integer.
@@ -81,8 +80,7 @@ public:
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
int getIntValue (const String& keyName,
const int defaultReturnValue = 0) const noexcept;
int getIntValue (StringRef keyName, int defaultReturnValue = 0) const noexcept;
/** Returns one of the properties as an double.
@@ -93,8 +91,7 @@ public:
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
double getDoubleValue (const String& keyName,
const double defaultReturnValue = 0.0) const noexcept;
double getDoubleValue (StringRef keyName, double defaultReturnValue = 0.0) const noexcept;
/** Returns one of the properties as an boolean.
@@ -108,8 +105,7 @@ public:
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
bool getBoolValue (const String& keyName,
const bool defaultReturnValue = false) const noexcept;
bool getBoolValue (StringRef keyName, bool defaultReturnValue = false) const noexcept;
/** Returns one of the properties as an XML element.
@@ -122,7 +118,7 @@ public:
@param keyName the name of the property to retrieve
*/
XmlElement* getXmlValue (const String& keyName) const;
XmlElement* getXmlValue (StringRef keyName) const;
//==============================================================================
/** Sets a named property.
@@ -150,10 +146,10 @@ public:
/** Deletes a property.
@param keyName the name of the property to delete. (This mustn't be an empty string)
*/
void removeValue (const String& keyName);
void removeValue (StringRef keyName);
/** Returns true if the properies include the given key. */
bool containsKey (const String& keyName) const noexcept;
bool containsKey (StringRef keyName) const noexcept;
/** Removes all values. */
void clear();


+ 42
- 41
source/modules/juce_core/files/juce_File.cpp View File

@@ -340,66 +340,67 @@ int File::hashCode() const { return fullPath.hashCode(); }
int64 File::hashCode64() const { return fullPath.hashCode64(); }
//==============================================================================
bool File::isAbsolutePath (const String& path)
bool File::isAbsolutePath (StringRef path)
{
return path.startsWithChar (separator)
return path.text[0] == separator
#if JUCE_WINDOWS
|| (path.isNotEmpty() && path[1] == ':');
|| (path.isNotEmpty() && path.text[1] == ':');
#else
|| path.startsWithChar ('~');
|| path.text[0] == '~';
#endif
}
File File::getChildFile (String relativePath) const
File File::getChildFile (StringRef relativePath) const
{
if (isAbsolutePath (relativePath))
return File (relativePath);
return File (String (relativePath.text));
if (relativePath.text[0] != '.')
return File (addTrailingSeparator (fullPath) + relativePath);
String path (fullPath);
// It's relative, so remove any ../ or ./ bits at the start..
if (relativePath[0] == '.')
#if JUCE_WINDOWS
if (relativePath.text.indexOf ((juce_wchar) '/') >= 0)
return getChildFile (String (relativePath.text).replaceCharacter ('/', '\\'));
#endif
while (relativePath[0] == '.')
{
#if JUCE_WINDOWS
relativePath = relativePath.replaceCharacter ('/', '\\');
#endif
const juce_wchar secondChar = relativePath.text[1];
while (relativePath[0] == '.')
if (secondChar == '.')
{
const juce_wchar secondChar = relativePath[1];
const juce_wchar thirdChar = relativePath.text[2];
if (secondChar == '.')
{
const juce_wchar thirdChar = relativePath[2];
if (thirdChar == 0 || thirdChar == separator)
{
const int lastSlash = path.lastIndexOfChar (separator);
if (lastSlash >= 0)
path = path.substring (0, lastSlash);
relativePath = relativePath.substring (3);
}
else
{
break;
}
}
else if (secondChar == separator)
if (thirdChar == 0 || thirdChar == separator)
{
relativePath = relativePath.substring (2);
const int lastSlash = path.lastIndexOfChar (separator);
if (lastSlash >= 0)
path = path.substring (0, lastSlash);
relativePath = relativePath.text + (thirdChar == 0 ? 2 : 3);
}
else
{
break;
}
}
else if (secondChar == separator)
{
relativePath = relativePath.text + 2;
}
else
{
break;
}
}
return File (addTrailingSeparator (path) + relativePath);
}
File File::getSiblingFile (const String& fileName) const
File File::getSiblingFile (StringRef fileName) const
{
return getParentDirectory().getChildFile (fileName);
}
@@ -602,23 +603,23 @@ String File::getFileExtension() const
return String::empty;
}
bool File::hasFileExtension (const String& possibleSuffix) const
bool File::hasFileExtension (StringRef possibleSuffix) const
{
if (possibleSuffix.isEmpty())
return fullPath.lastIndexOfChar ('.') <= fullPath.lastIndexOfChar (separator);
const int semicolon = possibleSuffix.indexOfChar (0, ';');
const int semicolon = possibleSuffix.text.indexOf ((juce_wchar) ';');
if (semicolon >= 0)
{
return hasFileExtension (possibleSuffix.substring (0, semicolon).trimEnd())
|| hasFileExtension (possibleSuffix.substring (semicolon + 1).trimStart());
return hasFileExtension (String (possibleSuffix.text).substring (0, semicolon).trimEnd())
|| hasFileExtension ((possibleSuffix.text + (semicolon + 1)).findEndOfWhitespace());
}
else
{
if (fullPath.endsWithIgnoreCase (possibleSuffix))
{
if (possibleSuffix.startsWithChar ('.'))
if (possibleSuffix.text[0] == '.')
return true;
const int dotPos = fullPath.length() - possibleSuffix.length() - 1;
@@ -631,7 +632,7 @@ bool File::hasFileExtension (const String& possibleSuffix) const
return false;
}
File File::withFileExtension (const String& newExtension) const
File File::withFileExtension (StringRef newExtension) const
{
if (fullPath.isEmpty())
return File::nonexistent;
@@ -642,7 +643,7 @@ File File::withFileExtension (const String& newExtension) const
if (i >= 0)
filePart = filePart.substring (0, i);
if (newExtension.isNotEmpty() && ! newExtension.startsWithChar ('.'))
if (newExtension.isNotEmpty() && newExtension.text[0] != '.')
filePart << '.';
return getSiblingFile (filePart + newExtension);
@@ -731,7 +732,7 @@ bool File::hasIdenticalContentTo (const File& other) const
if (in1.openedOk() && in2.openedOk())
{
const int bufferSize = 4096;
HeapBlock <char> buffer1 (bufferSize), buffer2 (bufferSize);
HeapBlock<char> buffer1 (bufferSize), buffer2 (bufferSize);
for (;;)
{
@@ -874,7 +875,7 @@ String File::getRelativePathFrom (const File& dir) const
}
//==============================================================================
File File::createTempFile (const String& fileNameEnding)
File File::createTempFile (StringRef fileNameEnding)
{
const File tempFile (getSpecialLocation (tempDirectory)
.getChildFile ("temp_" + String::toHexString (Random::getSystemRandom().nextInt()))


+ 6
- 6
source/modules/juce_core/files/juce_File.h View File

@@ -203,7 +203,7 @@ public:
@see getFileExtension, withFileExtension, getFileNameWithoutExtension
*/
bool hasFileExtension (const String& extensionToTest) const;
bool hasFileExtension (StringRef extensionToTest) const;
/** Returns a version of this file with a different file extension.
@@ -215,7 +215,7 @@ public:
@see getFileName, getFileExtension, hasFileExtension, getFileNameWithoutExtension
*/
File withFileExtension (const String& newExtension) const;
File withFileExtension (StringRef newExtension) const;
/** Returns the last part of the filename, without its file extension.
@@ -255,7 +255,7 @@ public:
@see getSiblingFile, getParentDirectory, getRelativePathFrom, isAChildOf
*/
File getChildFile (String relativeOrAbsolutePath) const;
File getChildFile (StringRef relativeOrAbsolutePath) const;
/** Returns a file which is in the same directory as this one.
@@ -263,7 +263,7 @@ public:
@see getChildFile, getParentDirectory
*/
File getSiblingFile (const String& siblingFileName) const;
File getSiblingFile (StringRef siblingFileName) const;
//==============================================================================
/** Returns the directory that contains this file or directory.
@@ -852,7 +852,7 @@ public:
This will try to return the name of a non-existent temp file.
To get the temp folder, you can use getSpecialLocation (File::tempDirectory).
*/
static File createTempFile (const String& fileNameEnding);
static File createTempFile (StringRef fileNameEnding);
//==============================================================================
@@ -908,7 +908,7 @@ public:
static bool areFileNamesCaseSensitive();
/** Returns true if the string seems to be a fully-specified absolute path. */
static bool isAbsolutePath (const String& path);
static bool isAbsolutePath (StringRef path);
/** Creates a file that simply contains this string, without doing the sanity-checking
that the normal constructors do.


+ 16
- 9
source/modules/juce_core/json/juce_JSON.cpp View File

@@ -330,7 +330,9 @@ public:
{
if (v.isString())
{
out << '"';
writeString (out, v.toString().getCharPointer());
out << '"';
}
else if (v.isVoid())
{
@@ -360,9 +362,6 @@ public:
}
}
private:
enum { indentSize = 2 };
static void writeEscapedChar (OutputStream& out, const unsigned short value)
{
out << "\\u" << String::toHexString ((int) value).paddedLeft ('0', 4);
@@ -370,15 +369,13 @@ private:
static void writeString (OutputStream& out, String::CharPointerType t)
{
out << '"';
for (;;)
{
const juce_wchar c (t.getAndAdvance());
switch (c)
{
case 0: out << '"'; return;
case 0: return;
case '\"': out << "\\\""; break;
case '\\': out << "\\\\"; break;
@@ -472,8 +469,9 @@ private:
if (! allOnOneLine)
writeSpaces (out, indentLevel + indentSize);
out << '"';
writeString (out, v->name);
out << ": ";
out << "\": ";
write (out, v->value, indentLevel + indentSize, allOnOneLine);
if (v->nextListItem.get() != nullptr)
@@ -494,6 +492,8 @@ private:
out << '}';
}
enum { indentSize = 2 };
};
//==============================================================================
@@ -534,6 +534,14 @@ void JSON::writeToStream (OutputStream& output, const var& data, const bool allO
JSONFormatter::write (output, data, 0, allOnOneLine);
}
String JSON::escapeString (StringRef s)
{
MemoryOutputStream mo;
JSONFormatter::writeString (mo, s.text);
return mo.toString();
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
@@ -616,8 +624,7 @@ public:
void runTest()
{
beginTest ("JSON");
Random r;
r.setSeedRandomly();
Random r = getRandom();
expect (JSON::parse (String::empty) == var::null);
expect (JSON::parse ("{}").isObject());


+ 3
- 0
source/modules/juce_core/json/juce_JSON.h View File

@@ -103,6 +103,9 @@ public:
const var& objectToFormat,
bool allOnOneLine = false);
/** Returns a version of a string with any extended characters escaped. */
static String escapeString (StringRef);
private:
//==============================================================================
JSON(); // This class can't be instantiated - just use its static methods.


+ 3
- 1
source/modules/juce_core/juce_core.h View File

@@ -119,7 +119,7 @@
/* Config: JUCE_CATCH_UNHANDLED_EXCEPTIONS
If enabled, this will add some exception-catching code to forward unhandled exceptions
to your JUCEApplication::unhandledException() callback.
to your JUCEApplicationBase::unhandledException() callback.
*/
#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
@@ -145,6 +145,7 @@
namespace juce
{
class StringRef;
class MemoryBlock;
class File;
class InputStream;
@@ -179,6 +180,7 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe
#endif
#include "text/juce_String.h"
#include "text/juce_StringRef.h"
#include "logging/juce_Logger.h"
#include "memory/juce_LeakedObjectDetector.h"
#include "memory/juce_ContainerDeletePolicy.h"


+ 1
- 1
source/modules/juce_core/juce_module_info View File

@@ -1,7 +1,7 @@
{
"id": "juce_core",
"name": "JUCE core classes",
"version": "2.1.2",
"version": "2.1.3",
"description": "The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.",
"website": "http://www.juce.com/juce",
"license": "ISC Permissive",


+ 2
- 2
source/modules/juce_core/maths/juce_BigInteger.cpp View File

@@ -953,10 +953,10 @@ String BigInteger::toString (const int base, const int minimumNumCharacters) con
return isNegative() ? "-" + s : s;
}
void BigInteger::parseString (const String& text, const int base)
void BigInteger::parseString (StringRef text, const int base)
{
clear();
String::CharPointerType t (text.getCharPointer().findEndOfWhitespace());
String::CharPointerType t (text.text.findEndOfWhitespace());
setNegative (*t == (juce_wchar) '-');


+ 1
- 1
source/modules/juce_core/maths/juce_BigInteger.h View File

@@ -282,7 +282,7 @@ public:
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
Any invalid characters will be ignored.
*/
void parseString (const String& text, int base);
void parseString (StringRef text, int base);
//==============================================================================
/** Turns the number into a block of binary data.


+ 15
- 21
source/modules/juce_core/maths/juce_Random.cpp View File

@@ -26,13 +26,11 @@
==============================================================================
*/
Random::Random (const int64 seedValue) noexcept
: seed (seedValue)
Random::Random (const int64 seedValue) noexcept : seed (seedValue)
{
}
Random::Random()
: seed (1)
Random::Random() : seed (1)
{
setSeedRandomly();
}
@@ -163,24 +161,20 @@ public:
{
beginTest ("Random");
for (int j = 10; --j >= 0;)
Random r = getRandom();
for (int i = 2000; --i >= 0;)
{
Random r;
r.setSeedRandomly();
for (int i = 20; --i >= 0;)
{
expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
expect (r.nextInt (1) == 0);
int n = r.nextInt (50) + 1;
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
n = r.nextInt (0x7ffffffe) + 1;
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
}
expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
expect (r.nextInt (1) == 0);
int n = r.nextInt (50) + 1;
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
n = r.nextInt (0x7ffffffe) + 1;
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
}
}
};


+ 4
- 7
source/modules/juce_core/maths/juce_Random.h View File

@@ -59,7 +59,6 @@ public:
~Random() noexcept;
/** Returns the next random 32 bit integer.
@returns a random integer from the full range 0x80000000 to 0x7fffffff
*/
int nextInt() noexcept;
@@ -71,29 +70,24 @@ public:
int nextInt (int maxValue) noexcept;
/** Returns the next 64-bit random number.
@returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff
*/
int64 nextInt64() noexcept;
/** Returns the next random floating-point number.
@returns a random value in the range 0 to 1.0
*/
float nextFloat() noexcept;
/** Returns the next random floating-point number.
@returns a random value in the range 0 to 1.0
*/
double nextDouble() noexcept;
/** Returns the next random boolean value.
*/
/** Returns the next random boolean value. */
bool nextBool() noexcept;
/** Returns a BigInteger containing a random number.
@returns a random value in the range 0 to (maximumValue - 1).
*/
BigInteger nextLargeNumber (const BigInteger& maximumValue);
@@ -108,6 +102,9 @@ public:
/** Resets this Random object to a given seed value. */
void setSeed (int64 newSeed) noexcept;
/** Returns the RNG's current seed. */
int64 getSeed() const noexcept { return seed; }
/** Merges this object's seed with another value.
This sets the seed to be a value created by combining the current seed and this
new value.


+ 11
- 13
source/modules/juce_core/memory/juce_MemoryBlock.cpp View File

@@ -317,11 +317,11 @@ void MemoryBlock::setBitRange (const size_t bitRangeStart, size_t numBits, int b
}
//==============================================================================
void MemoryBlock::loadFromHexString (const String& hex)
void MemoryBlock::loadFromHexString (StringRef hex)
{
ensureSize ((size_t) hex.length() >> 1);
char* dest = data;
String::CharPointerType t (hex.getCharPointer());
String::CharPointerType t (hex.text);
for (;;)
{
@@ -373,27 +373,27 @@ String MemoryBlock::toBase64Encoding() const
return destString;
}
bool MemoryBlock::fromBase64Encoding (const String& s)
bool MemoryBlock::fromBase64Encoding (StringRef s)
{
const int startPos = s.indexOfChar ('.') + 1;
String::CharPointerType dot (CharacterFunctions::find (s.text, CharPointer_ASCII (".")));
if (startPos <= 0)
if (dot.isEmpty())
return false;
const int numBytesNeeded = s.substring (0, startPos - 1).getIntValue();
const int numBytesNeeded = String (s.text, dot).getIntValue();
setSize ((size_t) numBytesNeeded, true);
const int numChars = s.length() - startPos;
String::CharPointerType srcChars (s.getCharPointer());
srcChars += startPos;
String::CharPointerType srcChars (dot + 1);
int pos = 0;
for (int i = 0; i < numChars; ++i)
for (;;)
{
const char c = (char) srcChars.getAndAdvance();
if (c == 0)
return true;
for (int j = 0; j < 64; ++j)
{
if (base64EncodingTable[j] == c)
@@ -404,6 +404,4 @@ bool MemoryBlock::fromBase64Encoding (const String& s)
}
}
}
return true;
}

+ 2
- 2
source/modules/juce_core/memory/juce_MemoryBlock.h View File

@@ -206,7 +206,7 @@ public:
@see String::toHexString()
*/
void loadFromHexString (const String& sourceHexString);
void loadFromHexString (StringRef sourceHexString);
//==============================================================================
/** Sets a number of bits in the memory block, treating it as a long binary sequence. */
@@ -235,7 +235,7 @@ public:
@see toBase64Encoding
*/
bool fromBase64Encoding (const String& encodedString);
bool fromBase64Encoding (StringRef encodedString);
private:


+ 8
- 22
source/modules/juce_core/misc/juce_Uuid.cpp View File

@@ -26,32 +26,13 @@
==============================================================================
*/
namespace
{
int64 getRandomSeedFromMACAddresses()
{
Array<MACAddress> result;
MACAddress::findAllAddresses (result);
Random r;
for (int i = 0; i < result.size(); ++i)
r.combineSeed (result[i].toInt64());
return r.nextInt64();
}
}
//==============================================================================
Uuid::Uuid()
{
// The normal random seeding is pretty good, but we'll throw some MAC addresses
// into the mix too, to make it very very unlikely that two UUIDs will ever be the same..
static Random r1 (getRandomSeedFromMACAddresses());
Random r2;
Random r;
for (size_t i = 0; i < sizeof (uuid); ++i)
uuid[i] = (uint8) (r1.nextInt() ^ r2.nextInt());
uuid[i] = (uint8) (r.nextInt (256));
}
Uuid::~Uuid() noexcept {}
@@ -70,6 +51,11 @@ Uuid& Uuid::operator= (const Uuid& other) noexcept
bool Uuid::operator== (const Uuid& other) const noexcept { return memcmp (uuid, other.uuid, sizeof (uuid)) == 0; }
bool Uuid::operator!= (const Uuid& other) const noexcept { return ! operator== (other); }
Uuid Uuid::null() noexcept
{
return Uuid ((const uint8*) nullptr);
}
bool Uuid::isNull() const noexcept
{
for (size_t i = 0; i < sizeof (uuid); ++i)
@@ -98,7 +84,7 @@ Uuid& Uuid::operator= (const String& uuidString)
return *this;
}
Uuid::Uuid (const uint8* const rawData)
Uuid::Uuid (const uint8* const rawData) noexcept
{
operator= (rawData);
}


+ 8
- 5
source/modules/juce_core/misc/juce_Uuid.h View File

@@ -51,17 +51,20 @@ public:
~Uuid() noexcept;
/** Creates a copy of another UUID. */
Uuid (const Uuid& other) noexcept;
Uuid (const Uuid&) noexcept;
/** Copies another UUID. */
Uuid& operator= (const Uuid& other) noexcept;
Uuid& operator= (const Uuid&) noexcept;
//==============================================================================
/** Returns true if the ID is zero. */
bool isNull() const noexcept;
bool operator== (const Uuid& other) const noexcept;
bool operator!= (const Uuid& other) const noexcept;
/** Returns a null Uuid object. */
static Uuid null() noexcept;
bool operator== (const Uuid&) const noexcept;
bool operator!= (const Uuid&) const noexcept;
//==============================================================================
/** Returns a stringified version of this UUID.
@@ -95,7 +98,7 @@ public:
/** Creates a UUID from a 16-byte array.
@see getRawData
*/
Uuid (const uint8* rawData);
Uuid (const uint8* rawData) noexcept;
/** Sets this UUID from 16-bytes of raw data. */
Uuid& operator= (const uint8* rawData) noexcept;


+ 10
- 18
source/modules/juce_core/native/juce_android_SystemStats.cpp View File

@@ -26,8 +26,7 @@
==============================================================================
*/
JNIClassBase::JNIClassBase (const char* classPath_)
: classPath (classPath_), classRef (0)
JNIClassBase::JNIClassBase (const char* cp) : classPath (cp), classRef (0)
{
getClasses().add (this);
}
@@ -129,8 +128,7 @@ AndroidSystem::AndroidSystem() : screenWidth (0), screenHeight (0), dpi (160)
{
}
void AndroidSystem::initialise (JNIEnv* env, jobject activity_,
jstring appFile_, jstring appDataDir_)
void AndroidSystem::initialise (JNIEnv* env, jobject act, jstring file, jstring dataDir)
{
screenWidth = screenHeight = 0;
dpi = 160;
@@ -141,9 +139,9 @@ void AndroidSystem::initialise (JNIEnv* env, jobject activity_,
systemInitialised = true;
#endif
activity = GlobalRef (activity_);
appFile = juceString (env, appFile_);
appDataDir = juceString (env, appDataDir_);
activity = GlobalRef (act);
appFile = juceString (env, file);
appDataDir = juceString (env, dataDir);
}
void AndroidSystem::shutdown (JNIEnv* env)
@@ -162,14 +160,12 @@ AndroidSystem android;
//==============================================================================
namespace AndroidStatsHelpers
{
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICMETHOD (getProperty, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;")
DECLARE_JNI_CLASS (SystemClass, "java/lang/System");
#undef JNI_CLASS_MEMBERS
//==============================================================================
String getSystemProperty (const String& name)
{
return juceString (LocalRef<jstring> ((jstring) getEnv()->CallStaticObjectMethod (SystemClass,
@@ -177,7 +173,6 @@ namespace AndroidStatsHelpers
javaString (name).get())));
}
//==============================================================================
String getLocaleValue (bool isRegion)
{
return juceString (LocalRef<jstring> ((jstring) getEnv()->CallStaticObjectMethod (JuceAppActivity,
@@ -236,16 +231,13 @@ int SystemStats::getPageSize()
//==============================================================================
String SystemStats::getLogonName()
{
const char* user = getenv ("USER");
if (const char* user = getenv ("USER"))
return CharPointer_UTF8 (user);
if (user == 0)
{
struct passwd* const pw = getpwuid (getuid());
if (pw != 0)
user = pw->pw_name;
}
if (struct passwd* const pw = getpwuid (getuid()))
return CharPointer_UTF8 (pw->pw_name);
return CharPointer_UTF8 (user);
return String::empty;
}
String SystemStats::getFullUserName()


+ 8
- 9
source/modules/juce_core/native/juce_linux_Files.cpp View File

@@ -165,13 +165,13 @@ File File::getSpecialLocation (const SpecialLocationType type)
{
case userHomeDirectory:
{
const char* homeDir = getenv ("HOME");
if (const char* homeDir = getenv ("HOME"))
return File (CharPointer_UTF8 (homeDir));
if (homeDir == nullptr)
if (struct passwd* const pw = getpwuid (getuid()))
homeDir = pw->pw_dir;
if (struct passwd* const pw = getpwuid (getuid()))
return File (CharPointer_UTF8 (pw->pw_dir));
return File (CharPointer_UTF8 (homeDir));
return File::nonexistent;
}
case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~");
@@ -179,7 +179,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
case userMoviesDirectory: return resolveXDGFolder ("XDG_VIDEOS_DIR", "~");
case userPicturesDirectory: return resolveXDGFolder ("XDG_PICTURES_DIR", "~");
case userDesktopDirectory: return resolveXDGFolder ("XDG_DESKTOP_DIR", "~/Desktop");
case userApplicationDataDirectory: return File ("~");
case userApplicationDataDirectory: return resolveXDGFolder ("XDG_CONFIG_HOME", "~");
case commonDocumentsDirectory:
case commonApplicationDataDirectory: return File ("/var");
case globalApplicationsDirectory: return File ("/usr");
@@ -247,10 +247,9 @@ bool File::moveToTrash() const
class DirectoryIterator::NativeIterator::Pimpl
{
public:
Pimpl (const File& directory, const String& wildCard_)
Pimpl (const File& directory, const String& wc)
: parentDir (File::addTrailingSeparator (directory.getFullPathName())),
wildCard (wildCard_),
dir (opendir (directory.getFullPathName().toUTF8()))
wildCard (wc), dir (opendir (directory.getFullPathName().toUTF8()))
{
}


+ 5
- 5
source/modules/juce_core/native/juce_linux_SystemStats.cpp View File

@@ -96,13 +96,13 @@ int SystemStats::getPageSize()
//==============================================================================
String SystemStats::getLogonName()
{
const char* user = getenv ("USER");
if (const char* user = getenv ("USER"))
return CharPointer_UTF8 (user);
if (user == nullptr)
if (passwd* const pw = getpwuid (getuid()))
user = pw->pw_name;
if (struct passwd* const pw = getpwuid (getuid()))
return CharPointer_UTF8 (pw->pw_name);
return CharPointer_UTF8 (user);
return String::empty;
}
String SystemStats::getFullUserName()


+ 2
- 2
source/modules/juce_core/native/juce_mac_Files.mm View File

@@ -205,7 +205,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
{
File tmp ("~/Library/Caches/" + juce_getExecutableFile().getFileNameWithoutExtension());
tmp.createDirectory();
return tmp.getFullPathName();
return File (tmp.getFullPathName());
}
#endif
case userMusicDirectory: resultPath = "~/Music"; break;
@@ -245,7 +245,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
buffer.calloc (size + 8);
_NSGetExecutablePath (buffer.getData(), &size);
return String::fromUTF8 (buffer, (int) size);
return File (String::fromUTF8 (buffer, (int) size));
}
default:


+ 20
- 16
source/modules/juce_core/native/juce_mac_Network.mm View File

@@ -250,18 +250,19 @@ public:
private:
//==============================================================================
struct DelegateClass : public ObjCClass <NSObject>
struct DelegateClass : public ObjCClass<NSObject>
{
DelegateClass() : ObjCClass <NSObject> ("JUCEAppDelegate_")
DelegateClass() : ObjCClass<NSObject> ("JUCEAppDelegate_")
{
addIvar <URLConnectionState*> ("state");
addIvar<URLConnectionState*> ("state");
addMethod (@selector (connection:didReceiveResponse:), didReceiveResponse, "v@:@@");
addMethod (@selector (connection:didFailWithError:), didFailWithError, "v@:@@");
addMethod (@selector (connection:didReceiveData:), didReceiveData, "v@:@@");
addMethod (@selector (connection:didReceiveResponse:), didReceiveResponse, "v@:@@");
addMethod (@selector (connection:didFailWithError:), didFailWithError, "v@:@@");
addMethod (@selector (connection:didReceiveData:), didReceiveData, "v@:@@");
addMethod (@selector (connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:totalBytesExpectedToWrite:),
connectionDidSendBodyData, "v@:@iii");
addMethod (@selector (connectionDidFinishLoading:), connectionDidFinishLoading, "v@:@");
connectionDidSendBodyData, "v@:@iii");
addMethod (@selector (connectionDidFinishLoading:), connectionDidFinishLoading, "v@:@");
addMethod (@selector (connection:willSendRequest:redirectResponse:), willSendRequest, "@@:@@");
registerClass();
}
@@ -285,6 +286,11 @@ private:
getState (self)->didReceiveData (newData);
}
static NSURLRequest* willSendRequest (id, SEL, NSURLConnection*, NSURLRequest* request, NSURLResponse*)
{
return request;
}
static void connectionDidSendBodyData (id self, SEL, NSURLConnection*, NSInteger, NSInteger totalBytesWritten, NSInteger totalBytesExpected)
{
getState (self)->didSendBodyData (totalBytesWritten, totalBytesExpected);
@@ -317,9 +323,8 @@ public:
if (responseHeaders != nullptr && connection != nullptr && connection->headers != nil)
{
NSEnumerator* enumerator = [connection->headers keyEnumerator];
NSString* key;
while ((key = [enumerator nextObject]) != nil)
while (NSString* key = [enumerator nextObject])
responseHeaders->set (nsStringToJuce (key),
nsStringToJuce ((NSString*) [connection->headers objectForKey: key]));
}
@@ -341,7 +346,7 @@ public:
JUCE_AUTORELEASEPOOL
{
const int bytesRead = connection->read (static_cast <char*> (buffer), bytesToRead);
const int bytesRead = connection->read (static_cast<char*> (buffer), bytesToRead);
position += bytesRead;
if (bytesRead == 0)
@@ -379,8 +384,7 @@ private:
const bool isPost;
const int timeOutMs;
void createConnection (URL::OpenStreamProgressCallback* progressCallback,
void* progressCallbackContext)
void createConnection (URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext)
{
jassert (connection == nullptr);
@@ -424,9 +428,9 @@ InputStream* URL::createNativeStream (const String& address, bool isPost, const
OpenStreamProgressCallback* progressCallback, void* progressCallbackContext,
const String& headers, const int timeOutMs, StringPairArray* responseHeaders)
{
ScopedPointer <WebInputStream> wi (new WebInputStream (address, isPost, postData,
progressCallback, progressCallbackContext,
headers, timeOutMs, responseHeaders));
ScopedPointer<WebInputStream> wi (new WebInputStream (address, isPost, postData,
progressCallback, progressCallbackContext,
headers, timeOutMs, responseHeaders));
return wi->isError() ? nullptr : wi.release();
}

+ 6
- 21
source/modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -34,29 +34,14 @@ CriticalSection::CriticalSection() noexcept
#if ! JUCE_ANDROID
pthread_mutexattr_setprotocol (&atts, PTHREAD_PRIO_INHERIT);
#endif
pthread_mutex_init (&internal, &atts);
}
CriticalSection::~CriticalSection() noexcept
{
pthread_mutex_destroy (&internal);
}
void CriticalSection::enter() const noexcept
{
pthread_mutex_lock (&internal);
}
bool CriticalSection::tryEnter() const noexcept
{
return pthread_mutex_trylock (&internal) == 0;
}
void CriticalSection::exit() const noexcept
{
pthread_mutex_unlock (&internal);
pthread_mutex_init (&lock, &atts);
pthread_mutexattr_destroy (&atts);
}
CriticalSection::~CriticalSection() noexcept { pthread_mutex_destroy (&lock); }
void CriticalSection::enter() const noexcept { pthread_mutex_lock (&lock); }
bool CriticalSection::tryEnter() const noexcept { return pthread_mutex_trylock (&lock) == 0; }
void CriticalSection::exit() const noexcept { pthread_mutex_unlock (&lock); }
//==============================================================================
WaitableEvent::WaitableEvent (const bool useManualReset) noexcept


+ 1
- 1
source/modules/juce_core/native/juce_win32_Network.cpp View File

@@ -58,7 +58,7 @@ public:
if (HttpQueryInfo (request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer.getData(), &bufferSizeBytes, 0))
{
StringArray headersArray;
headersArray.addLines (reinterpret_cast <const WCHAR*> (buffer.getData()));
headersArray.addLines (String (reinterpret_cast<const WCHAR*> (buffer.getData())));
for (int i = 0; i < headersArray.size(); ++i)
{


+ 1
- 1
source/modules/juce_core/native/juce_win32_Registry.cpp View File

@@ -218,7 +218,7 @@ bool WindowsRegistry::registerFileAssociation (const String& fileExtension,
&& setValue (key + "\\shell\\open\\command\\", targetExecutable.getFullPathName() + " \"%1\"", mode)
&& (iconResourceNumber == 0
|| setValue (key + "\\DefaultIcon\\",
targetExecutable.getFullPathName() + "," + String (-iconResourceNumber)));
targetExecutable.getFullPathName() + "," + String (iconResourceNumber)));
}
// These methods are deprecated:


+ 25
- 46
source/modules/juce_core/native/juce_win32_Threads.cpp View File

@@ -28,6 +28,13 @@
HWND juce_messageWindowHandle = 0; // (this is used by other parts of the codebase)
void* getUser32Function (const char* functionName)
{
HMODULE module = GetModuleHandleA ("user32.dll");
jassert (module != 0);
return (void*) GetProcAddress (module, functionName);
}
//==============================================================================
#if ! JUCE_USE_INTRINSICS
// In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in
@@ -55,59 +62,33 @@ __int64 juce_InterlockedCompareExchange64 (volatile __int64* value, __int64 newV
CriticalSection::CriticalSection() noexcept
{
// (just to check the MS haven't changed this structure and broken things...)
#if JUCE_VC7_OR_EARLIER
#if JUCE_VC7_OR_EARLIER
static_jassert (sizeof (CRITICAL_SECTION) <= 24);
#else
static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (internal));
#endif
InitializeCriticalSection ((CRITICAL_SECTION*) internal);
}
CriticalSection::~CriticalSection() noexcept
{
DeleteCriticalSection ((CRITICAL_SECTION*) internal);
}
#else
static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (lock));
#endif
void CriticalSection::enter() const noexcept
{
EnterCriticalSection ((CRITICAL_SECTION*) internal);
InitializeCriticalSection ((CRITICAL_SECTION*) lock);
}
bool CriticalSection::tryEnter() const noexcept
{
return TryEnterCriticalSection ((CRITICAL_SECTION*) internal) != FALSE;
}
CriticalSection::~CriticalSection() noexcept { DeleteCriticalSection ((CRITICAL_SECTION*) lock); }
void CriticalSection::enter() const noexcept { EnterCriticalSection ((CRITICAL_SECTION*) lock); }
bool CriticalSection::tryEnter() const noexcept { return TryEnterCriticalSection ((CRITICAL_SECTION*) lock) != FALSE; }
void CriticalSection::exit() const noexcept { LeaveCriticalSection ((CRITICAL_SECTION*) lock); }
void CriticalSection::exit() const noexcept
{
LeaveCriticalSection ((CRITICAL_SECTION*) internal);
}
//==============================================================================
WaitableEvent::WaitableEvent (const bool manualReset) noexcept
: internal (CreateEvent (0, manualReset ? TRUE : FALSE, FALSE, 0))
{
}
: handle (CreateEvent (0, manualReset ? TRUE : FALSE, FALSE, 0)) {}
WaitableEvent::~WaitableEvent() noexcept
{
CloseHandle (internal);
}
bool WaitableEvent::wait (const int timeOutMillisecs) const noexcept
{
return WaitForSingleObject (internal, (DWORD) timeOutMillisecs) == WAIT_OBJECT_0;
}
WaitableEvent::~WaitableEvent() noexcept { CloseHandle (handle); }
void WaitableEvent::signal() const noexcept
{
SetEvent (internal);
}
void WaitableEvent::signal() const noexcept { SetEvent (handle); }
void WaitableEvent::reset() const noexcept { ResetEvent (handle); }
void WaitableEvent::reset() const noexcept
bool WaitableEvent::wait (const int timeOutMs) const noexcept
{
ResetEvent (internal);
return WaitForSingleObject (handle, (DWORD) timeOutMs) == WAIT_OBJECT_0;
}
//==============================================================================
@@ -229,17 +210,15 @@ static SleepEvent sleepEvent;
void JUCE_CALLTYPE Thread::sleep (const int millisecs)
{
jassert (millisecs >= 0);
if (millisecs >= 10 || sleepEvent.handle == 0)
{
Sleep ((DWORD) millisecs);
}
else
{
// unlike Sleep() this is guaranteed to return to the current thread after
// the time expires, so we'll use this for short waits, which are more likely
// to need to be accurate
WaitForSingleObject (sleepEvent.handle, (DWORD) millisecs);
}
}
void Thread::yield()
@@ -250,7 +229,7 @@ void Thread::yield()
//==============================================================================
static int lastProcessPriority = -1;
// called by WindowDriver because Windows does weird things to process priority
// called when the app gains focus because Windows does weird things to process priority
// when you swap apps, and this forces an update when the app is brought to the front.
void juce_repeatLastProcessPriority()
{


+ 15
- 14
source/modules/juce_core/network/juce_URL.cpp View File

@@ -30,8 +30,7 @@ URL::URL()
{
}
URL::URL (const String& url_)
: url (url_)
URL::URL (const String& u) : url (u)
{
int i = url.indexOfChar ('?');
@@ -198,9 +197,11 @@ namespace URLHelpers
data << getMangledParameters (url)
<< url.getPostData();
// just a short text attachment, so use simple url encoding..
headers << "Content-Type: application/x-www-form-urlencoded\r\nContent-length: "
<< (int) data.getDataSize() << "\r\n";
// if the user-supplied headers didn't contain a content-type, add one now..
if (! headers.containsIgnoreCase ("Content-Type"))
headers << "Content-Type: application/x-www-form-urlencoded\r\n";
headers << "Content-length: " << (int) data.getDataSize() << "\r\n";
}
}
@@ -313,25 +314,25 @@ bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress)
return atSign > 0
&& possibleEmailAddress.lastIndexOfChar ('.') > (atSign + 1)
&& (! possibleEmailAddress.endsWithChar ('.'));
&& ! possibleEmailAddress.endsWithChar ('.');
}
//==============================================================================
InputStream* URL::createInputStream (const bool usePostCommand,
OpenStreamProgressCallback* const progressCallback,
void* const progressCallbackContext,
const String& extraHeaders,
String headers,
const int timeOutMs,
StringPairArray* const responseHeaders) const
{
String headers;
MemoryBlock headersAndPostData;
if (! headers.endsWithChar ('\n'))
headers << "\r\n";
if (usePostCommand)
URLHelpers::createHeadersAndPostData (*this, headers, headersAndPostData);
headers += extraHeaders;
if (! headers.endsWithChar ('\n'))
headers << "\r\n";
@@ -344,7 +345,7 @@ InputStream* URL::createInputStream (const bool usePostCommand,
bool URL::readEntireBinaryStream (MemoryBlock& destData,
const bool usePostCommand) const
{
const ScopedPointer <InputStream> in (createInputStream (usePostCommand));
const ScopedPointer<InputStream> in (createInputStream (usePostCommand));
if (in != nullptr)
{
@@ -357,7 +358,7 @@ bool URL::readEntireBinaryStream (MemoryBlock& destData,
String URL::readEntireTextStream (const bool usePostCommand) const
{
const ScopedPointer <InputStream> in (createInputStream (usePostCommand));
const ScopedPointer<InputStream> in (createInputStream (usePostCommand));
if (in != nullptr)
return in->readEntireStreamAsString();
@@ -391,10 +392,10 @@ URL URL::withFileToUpload (const String& parameterName,
return u;
}
URL URL::withPOSTData (const String& postData_) const
URL URL::withPOSTData (const String& newPostData) const
{
URL u (*this);
u.postData = postData_;
u.postData = newPostData;
return u;
}


+ 1
- 1
source/modules/juce_core/network/juce_URL.h View File

@@ -251,7 +251,7 @@ public:
InputStream* createInputStream (bool usePostCommand,
OpenStreamProgressCallback* progressCallback = nullptr,
void* progressCallbackContext = nullptr,
const String& extraHeaders = String::empty,
String extraHeaders = String::empty,
int connectionTimeOutMs = 0,
StringPairArray* responseHeaders = nullptr) const;


+ 3
- 4
source/modules/juce_core/streams/juce_MemoryInputStream.cpp View File

@@ -104,12 +104,12 @@ public:
void runTest()
{
beginTest ("Basics");
Random r;
Random r = getRandom();
int randomInt = r.nextInt();
int64 randomInt64 = r.nextInt64();
double randomDouble = r.nextDouble();
String randomString (createRandomWideCharString());
String randomString (createRandomWideCharString (r));
MemoryOutputStream mo;
mo.writeInt (randomInt);
@@ -132,10 +132,9 @@ public:
expect (mi.readDoubleBigEndian() == randomDouble);
}
static String createRandomWideCharString()
static String createRandomWideCharString (Random& r)
{
juce_wchar buffer [50] = { 0 };
Random r;
for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
{


+ 3
- 3
source/modules/juce_core/system/juce_PlatformDefs.h View File

@@ -222,17 +222,17 @@ namespace juce
#if ! JUCE_MODULE_AVAILABLE_juce_gui_basics
#define JUCE_CATCH_EXCEPTION JUCE_CATCH_ALL
#else
/** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication
/** Used in try-catch blocks, this macro will send exceptions to the JUCEApplicationBase
object so they can be logged by the application if it wants to.
*/
#define JUCE_CATCH_EXCEPTION \
catch (const std::exception& e) \
{ \
juce::JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \
juce::JUCEApplicationBase::sendUnhandledException (&e, __FILE__, __LINE__); \
} \
catch (...) \
{ \
juce::JUCEApplication::sendUnhandledException (nullptr, __FILE__, __LINE__); \
juce::JUCEApplicationBase::sendUnhandledException (nullptr, __FILE__, __LINE__); \
}
#endif


+ 1
- 1
source/modules/juce_core/system/juce_StandardHeader.h View File

@@ -36,7 +36,7 @@
*/
#define JUCE_MAJOR_VERSION 2
#define JUCE_MINOR_VERSION 1
#define JUCE_BUILDNUMBER 2
#define JUCE_BUILDNUMBER 3
/** Current Juce version number.


+ 20
- 0
source/modules/juce_core/text/juce_CharacterFunctions.h View File

@@ -280,6 +280,26 @@ public:
return isNeg ? -v : v;
}
template <typename ResultType>
struct HexParser
{
template <typename CharPointerType>
static ResultType parse (CharPointerType t) noexcept
{
ResultType result = 0;
while (! t.isEmpty())
{
const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance());
if (hexValue >= 0)
result = (result << 4) | hexValue;
}
return result;
}
};
//==============================================================================
/** Counts the number of characters in a given string, stopping if the count exceeds
a specified limit. */


+ 4
- 1
source/modules/juce_core/text/juce_Identifier.h View File

@@ -38,7 +38,7 @@
from a string, so it's much faster to keep a static identifier object to refer
to frequently-used names, rather than constructing them each time you need it.
@see NamedPropertySet, ValueTree
@see NamedValueSet, ValueTree
*/
class JUCE_API Identifier
{
@@ -82,6 +82,9 @@ public:
/** Returns this identifier's raw string pointer. */
const String::CharPointerType getCharPointer() const noexcept { return name; }
/** Returns this identifier as a StringRef. */
operator StringRef() const noexcept { return name; }
/** Returns true if this Identifier is not null */
bool isValid() const noexcept { return name.getAddress() != nullptr; }


+ 8
- 0
source/modules/juce_core/text/juce_NewLine.h View File

@@ -53,6 +53,11 @@ public:
@see getDefault()
*/
operator String() const { return getDefault(); }
/** Returns the default new-line sequence that the library uses.
@see OutputStream::setNewLineString()
*/
operator StringRef() const noexcept { return getDefault(); }
};
//==============================================================================
@@ -74,5 +79,8 @@ extern NewLine newLine;
*/
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&);
#if JUCE_STRING_UTF_TYPE != 8 && ! defined (DOXYGEN)
inline String operator+ (String s1, const NewLine&) { return s1 += NewLine::getDefault(); }
#endif
#endif // JUCE_NEWLINE_H_INCLUDED

+ 255
- 287
source/modules/juce_core/text/juce_String.cpp
File diff suppressed because it is too large
View File


+ 45
- 38
source/modules/juce_core/text/juce_String.h View File

@@ -296,6 +296,9 @@ public:
/** Case-insensitive comparison with another string. */
bool equalsIgnoreCase (const String& other) const noexcept;
/** Case-insensitive comparison with another string. */
bool equalsIgnoreCase (StringRef other) const noexcept;
/** Case-insensitive comparison with another string. */
bool equalsIgnoreCase (const wchar_t* other) const noexcept;
@@ -340,7 +343,7 @@ public:
If the parameter is an empty string, this will always return true.
Uses a case-sensitive comparison.
*/
bool startsWith (const String& text) const noexcept;
bool startsWith (StringRef text) const noexcept;
/** Tests whether the string begins with a particular character.
If the character is 0, this will always return false.
@@ -352,13 +355,13 @@ public:
If the parameter is an empty string, this will always return true.
Uses a case-insensitive comparison.
*/
bool startsWithIgnoreCase (const String& text) const noexcept;
bool startsWithIgnoreCase (StringRef text) const noexcept;
/** Tests whether the string ends with another string.
If the parameter is an empty string, this will always return true.
Uses a case-sensitive comparison.
*/
bool endsWith (const String& text) const noexcept;
bool endsWith (StringRef text) const noexcept;
/** Tests whether the string ends with a particular character.
If the character is 0, this will always return false.
@@ -370,13 +373,13 @@ public:
If the parameter is an empty string, this will always return true.
Uses a case-insensitive comparison.
*/
bool endsWithIgnoreCase (const String& text) const noexcept;
bool endsWithIgnoreCase (StringRef text) const noexcept;
/** Tests whether the string contains another substring.
If the parameter is an empty string, this will always return true.
Uses a case-sensitive comparison.
*/
bool contains (const String& text) const noexcept;
bool contains (StringRef text) const noexcept;
/** Tests whether the string contains a particular character.
Uses a case-sensitive comparison.
@@ -386,7 +389,7 @@ public:
/** Tests whether the string contains another substring.
Uses a case-insensitive comparison.
*/
bool containsIgnoreCase (const String& text) const noexcept;
bool containsIgnoreCase (StringRef text) const noexcept;
/** Tests whether the string contains another substring as a distinct word.
@@ -394,7 +397,7 @@ public:
non-alphanumeric characters
@see indexOfWholeWord, containsWholeWordIgnoreCase
*/
bool containsWholeWord (const String& wordToLookFor) const noexcept;
bool containsWholeWord (StringRef wordToLookFor) const noexcept;
/** Tests whether the string contains another substring as a distinct word.
@@ -402,7 +405,7 @@ public:
non-alphanumeric characters
@see indexOfWholeWordIgnoreCase, containsWholeWord
*/
bool containsWholeWordIgnoreCase (const String& wordToLookFor) const noexcept;
bool containsWholeWordIgnoreCase (StringRef wordToLookFor) const noexcept;
/** Finds an instance of another substring if it exists as a distinct word.
@@ -411,7 +414,7 @@ public:
found, then it will return -1
@see indexOfWholeWordIgnoreCase, containsWholeWord
*/
int indexOfWholeWord (const String& wordToLookFor) const noexcept;
int indexOfWholeWord (StringRef wordToLookFor) const noexcept;
/** Finds an instance of another substring if it exists as a distinct word.
@@ -420,7 +423,7 @@ public:
found, then it will return -1
@see indexOfWholeWord, containsWholeWordIgnoreCase
*/
int indexOfWholeWordIgnoreCase (const String& wordToLookFor) const noexcept;
int indexOfWholeWordIgnoreCase (StringRef wordToLookFor) const noexcept;
/** Looks for any of a set of characters in the string.
Uses a case-sensitive comparison.
@@ -428,7 +431,7 @@ public:
@returns true if the string contains any of the characters from
the string that is passed in.
*/
bool containsAnyOf (const String& charactersItMightContain) const noexcept;
bool containsAnyOf (StringRef charactersItMightContain) const noexcept;
/** Looks for a set of characters in the string.
Uses a case-sensitive comparison.
@@ -437,7 +440,7 @@ public:
the parameter string. If this string is empty, the return value will
always be true.
*/
bool containsOnly (const String& charactersItMightContain) const noexcept;
bool containsOnly (StringRef charactersItMightContain) const noexcept;
/** Returns true if this string contains any non-whitespace characters.
@@ -455,7 +458,7 @@ public:
This isn't a full-blown regex though! The only wildcard characters supported
are "*" and "?". It's mainly intended for filename pattern matching.
*/
bool matchesWildcard (const String& wildcard, bool ignoreCase) const noexcept;
bool matchesWildcard (StringRef wildcard, bool ignoreCase) const noexcept;
//==============================================================================
// Substring location methods..
@@ -488,7 +491,7 @@ public:
@see indexOfChar, lastIndexOfAnyOf
*/
int indexOfAnyOf (const String& charactersToLookFor,
int indexOfAnyOf (StringRef charactersToLookFor,
int startIndex = 0,
bool ignoreCase = false) const noexcept;
@@ -497,7 +500,7 @@ public:
@returns the index of the first occurrence of this substring, or -1 if it's not found.
If textToLookFor is an empty string, this will always return 0.
*/
int indexOf (const String& textToLookFor) const noexcept;
int indexOf (StringRef textToLookFor) const noexcept;
/** Searches for a substring within this string.
Uses a case-sensitive comparison.
@@ -506,14 +509,14 @@ public:
@returns the index of the first occurrence of this substring, or -1 if it's not found.
If textToLookFor is an empty string, this will always return -1.
*/
int indexOf (int startIndex, const String& textToLookFor) const noexcept;
int indexOf (int startIndex, StringRef textToLookFor) const noexcept;
/** Searches for a substring within this string.
Uses a case-insensitive comparison.
@returns the index of the first occurrence of this substring, or -1 if it's not found.
If textToLookFor is an empty string, this will always return 0.
*/
int indexOfIgnoreCase (const String& textToLookFor) const noexcept;
int indexOfIgnoreCase (StringRef textToLookFor) const noexcept;
/** Searches for a substring within this string.
Uses a case-insensitive comparison.
@@ -522,7 +525,7 @@ public:
@returns the index of the first occurrence of this substring, or -1 if it's not found.
If textToLookFor is an empty string, this will always return -1.
*/
int indexOfIgnoreCase (int startIndex, const String& textToLookFor) const noexcept;
int indexOfIgnoreCase (int startIndex, StringRef textToLookFor) const noexcept;
/** Searches for a character inside this string (working backwards from the end of the string).
Uses a case-sensitive comparison.
@@ -535,14 +538,14 @@ public:
@returns the index of the start of the last occurrence of the substring within this string,
or -1 if it's not found. If textToLookFor is an empty string, this will always return -1.
*/
int lastIndexOf (const String& textToLookFor) const noexcept;
int lastIndexOf (StringRef textToLookFor) const noexcept;
/** Searches for a substring inside this string (working backwards from the end of the string).
Uses a case-insensitive comparison.
@returns the index of the start of the last occurrence of the substring within this string, or -1
if it's not found. If textToLookFor is an empty string, this will always return -1.
*/
int lastIndexOfIgnoreCase (const String& textToLookFor) const noexcept;
int lastIndexOfIgnoreCase (StringRef textToLookFor) const noexcept;
/** Returns the index of the last character in this string that matches one of the
characters passed-in to this method.
@@ -556,7 +559,7 @@ public:
@see lastIndexOf, indexOfAnyOf
*/
int lastIndexOfAnyOf (const String& charactersToLookFor,
int lastIndexOfAnyOf (StringRef charactersToLookFor,
bool ignoreCase = false) const noexcept;
@@ -640,7 +643,7 @@ public:
@see upToFirstOccurrenceOf, fromLastOccurrenceOf
*/
String fromFirstOccurrenceOf (const String& substringToStartFrom,
String fromFirstOccurrenceOf (StringRef substringToStartFrom,
bool includeSubStringInResult,
bool ignoreCase) const;
@@ -652,7 +655,7 @@ public:
@see fromFirstOccurrenceOf, upToLastOccurrenceOf
*/
String fromLastOccurrenceOf (const String& substringToFind,
String fromLastOccurrenceOf (StringRef substringToFind,
bool includeSubStringInResult,
bool ignoreCase) const;
@@ -669,7 +672,7 @@ public:
@see upToLastOccurrenceOf, fromFirstOccurrenceOf
*/
String upToFirstOccurrenceOf (const String& substringToEndWith,
String upToFirstOccurrenceOf (StringRef substringToEndWith,
bool includeSubStringInResult,
bool ignoreCase) const;
@@ -680,7 +683,7 @@ public:
@see upToFirstOccurrenceOf, fromFirstOccurrenceOf
*/
String upToLastOccurrenceOf (const String& substringToFind,
String upToLastOccurrenceOf (StringRef substringToFind,
bool includeSubStringInResult,
bool ignoreCase) const;
@@ -700,7 +703,7 @@ public:
@param charactersToTrim the set of characters to remove.
@see trim, trimStart, trimCharactersAtEnd
*/
String trimCharactersAtStart (const String& charactersToTrim) const;
String trimCharactersAtStart (StringRef charactersToTrim) const;
/** Returns a copy of this string, having removed a specified set of characters from its end.
Characters are removed from the end of the string until it finds one that is not in the
@@ -708,7 +711,7 @@ public:
@param charactersToTrim the set of characters to remove.
@see trim, trimEnd, trimCharactersAtStart
*/
String trimCharactersAtEnd (const String& charactersToTrim) const;
String trimCharactersAtEnd (StringRef charactersToTrim) const;
//==============================================================================
/** Returns an upper-case version of this string. */
@@ -735,7 +738,7 @@ public:
*/
String replaceSection (int startIndex,
int numCharactersToReplace,
const String& stringToInsert) const;
StringRef stringToInsert) const;
/** Replaces all occurrences of a substring with another string.
@@ -744,8 +747,8 @@ public:
Note that this is a const method, and won't alter the string itself.
*/
String replace (const String& stringToReplace,
const String& stringToInsertInstead,
String replace (StringRef stringToReplace,
StringRef stringToInsertInstead,
bool ignoreCase = false) const;
/** Returns a string with all occurrences of a character replaced with a different one. */
@@ -762,8 +765,8 @@ public:
Note that this is a const method, and won't affect the string itself.
*/
String replaceCharacters (const String& charactersToReplace,
const String& charactersToInsertInstead) const;
String replaceCharacters (StringRef charactersToReplace,
StringRef charactersToInsertInstead) const;
/** Returns a version of this string that only retains a fixed set of characters.
@@ -774,7 +777,7 @@ public:
Note that this is a const method, and won't alter the string itself.
*/
String retainCharacters (const String& charactersToRetain) const;
String retainCharacters (StringRef charactersToRetain) const;
/** Returns a version of this string with a set of characters removed.
@@ -785,14 +788,14 @@ public:
Note that this is a const method, and won't alter the string itself.
*/
String removeCharacters (const String& charactersToRemove) const;
String removeCharacters (StringRef charactersToRemove) const;
/** Returns a section from the start of the string that only contains a certain set of characters.
This returns the leftmost section of the string, up to (and not including) the
first character that doesn't appear in the string passed in.
*/
String initialSectionContainingOnly (const String& permittedCharacters) const;
String initialSectionContainingOnly (StringRef permittedCharacters) const;
/** Returns a section from the start of the string that only contains a certain set of characters.
@@ -800,7 +803,7 @@ public:
first character that occurs in the string passed in. (If none of the specified
characters are found in the string, the return value will just be the original string).
*/
String initialSectionNotContaining (const String& charactersToStopAt) const;
String initialSectionNotContaining (StringRef charactersToStopAt) const;
//==============================================================================
/** Checks whether the string might be in quotation marks.
@@ -843,7 +846,7 @@ public:
@param stringToRepeat the string to repeat
@param numberOfTimesToRepeat how many times to repeat it
*/
static String repeatedString (const String& stringToRepeat,
static String repeatedString (StringRef stringToRepeat,
int numberOfTimesToRepeat);
/** Returns a copy of this string with the specified character repeatedly added to its
@@ -950,7 +953,6 @@ public:
int getIntValue() const noexcept;
/** Reads the value of the string as a decimal number (up to 64 bits in size).
@returns the value of the string as a 64 bit signed base-10 integer.
*/
int64 getLargeIntValue() const noexcept;
@@ -1293,6 +1295,7 @@ JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const CharPointer
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const CharPointer_UTF16 string2) noexcept;
/** Case-sensitive comparison of two strings. */
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const CharPointer_UTF32 string2) noexcept;
/** Case-sensitive comparison of two strings. */
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const String& string2) noexcept;
/** Case-sensitive comparison of two strings. */
@@ -1305,6 +1308,7 @@ JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const CharPointer
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const CharPointer_UTF16 string2) noexcept;
/** Case-sensitive comparison of two strings. */
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const CharPointer_UTF32 string2) noexcept;
/** Case-sensitive comparison of two strings. */
JUCE_API bool JUCE_CALLTYPE operator> (const String& string1, const String& string2) noexcept;
/** Case-sensitive comparison of two strings. */
@@ -1336,5 +1340,8 @@ std::basic_ostream <wchar_t, traits>& JUCE_CALLTYPE operator<< (std::basic_ostre
/** Writes a string to an OutputStream as UTF8. */
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& stringToWrite);
/** Writes a string to an OutputStream as UTF8. */
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, StringRef stringToWrite);
#endif // JUCE_STRING_H_INCLUDED

+ 33
- 85
source/modules/juce_core/text/juce_StringArray.cpp View File

@@ -47,47 +47,29 @@ StringArray::StringArray (const String& firstValue)
strings.add (firstValue);
}
namespace StringArrayHelpers
{
template <typename CharType>
void addArray (Array<String>& dest, const CharType* const* strings)
{
if (strings != nullptr)
while (*strings != nullptr)
dest.add (*strings++);
}
template <typename Type>
void addArray (Array<String>& dest, const Type* const strings, const int numberOfStrings)
{
for (int i = 0; i < numberOfStrings; ++i)
dest.add (strings [i]);
}
}
StringArray::StringArray (const String* initialStrings, int numberOfStrings)
{
StringArrayHelpers::addArray (strings, initialStrings, numberOfStrings);
strings.addArray (initialStrings, numberOfStrings);
}
StringArray::StringArray (const char* const* const initialStrings)
StringArray::StringArray (const char* const* initialStrings)
{
StringArrayHelpers::addArray (strings, initialStrings);
strings.addNullTerminatedArray (initialStrings);
}
StringArray::StringArray (const char* const* const initialStrings, const int numberOfStrings)
StringArray::StringArray (const char* const* initialStrings, int numberOfStrings)
{
StringArrayHelpers::addArray (strings, initialStrings, numberOfStrings);
strings.addArray (initialStrings, numberOfStrings);
}
StringArray::StringArray (const wchar_t* const* const initialStrings)
StringArray::StringArray (const wchar_t* const* initialStrings)
{
StringArrayHelpers::addArray (strings, initialStrings);
strings.addNullTerminatedArray (initialStrings);
}
StringArray::StringArray (const wchar_t* const* const initialStrings, const int numberOfStrings)
StringArray::StringArray (const wchar_t* const* initialStrings, int numberOfStrings)
{
StringArrayHelpers::addArray (strings, initialStrings, numberOfStrings);
strings.addArray (initialStrings, numberOfStrings);
}
StringArray& StringArray::operator= (const StringArray& other)
@@ -110,14 +92,7 @@ StringArray::~StringArray()
bool StringArray::operator== (const StringArray& other) const noexcept
{
if (other.size() != size())
return false;
for (int i = size(); --i >= 0;)
if (other.strings.getReference(i) != strings.getReference(i))
return false;
return true;
return strings == other.strings;
}
bool StringArray::operator!= (const StringArray& other) const noexcept
@@ -150,7 +125,6 @@ const String& StringArray::operator[] (const int index) const noexcept
String& StringArray::getReference (const int index) noexcept
{
jassert (isPositiveAndBelow (index, strings.size()));
return strings.getReference (index);
}
@@ -190,25 +164,12 @@ void StringArray::set (const int index, const String& newString)
strings.set (index, newString);
}
bool StringArray::contains (const String& stringToLookFor, const bool ignoreCase) const
bool StringArray::contains (StringRef stringToLookFor, const bool ignoreCase) const
{
if (ignoreCase)
{
for (int i = size(); --i >= 0;)
if (strings.getReference(i).equalsIgnoreCase (stringToLookFor))
return true;
}
else
{
for (int i = size(); --i >= 0;)
if (stringToLookFor == strings.getReference(i))
return true;
}
return false;
return indexOf (stringToLookFor, ignoreCase) >= 0;
}
int StringArray::indexOf (const String& stringToLookFor, const bool ignoreCase, int i) const
int StringArray::indexOf (StringRef stringToLookFor, const bool ignoreCase, int i) const
{
if (i < 0)
i = 0;
@@ -217,23 +178,15 @@ int StringArray::indexOf (const String& stringToLookFor, const bool ignoreCase,
if (ignoreCase)
{
while (i < numElements)
{
for (; i < numElements; ++i)
if (strings.getReference(i).equalsIgnoreCase (stringToLookFor))
return i;
++i;
}
}
else
{
while (i < numElements)
{
for (; i < numElements; ++i)
if (stringToLookFor == strings.getReference (i))
return i;
++i;
}
}
return -1;
@@ -245,8 +198,7 @@ void StringArray::remove (const int index)
strings.remove (index);
}
void StringArray::removeString (const String& stringToRemove,
const bool ignoreCase)
void StringArray::removeString (StringRef stringToRemove, const bool ignoreCase)
{
if (ignoreCase)
{
@@ -325,7 +277,7 @@ void StringArray::move (const int currentIndex, int newIndex) noexcept
//==============================================================================
String StringArray::joinIntoString (const String& separator, int start, int numberToJoin) const
String StringArray::joinIntoString (StringRef separator, int start, int numberToJoin) const
{
const int last = (numberToJoin < 0) ? size()
: jmin (size(), start + numberToJoin);
@@ -339,7 +291,7 @@ String StringArray::joinIntoString (const String& separator, int start, int numb
if (start == last - 1)
return strings.getReference (start);
const size_t separatorBytes = separator.getCharPointer().sizeInBytes() - sizeof (String::CharPointerType::CharType);
const size_t separatorBytes = separator.text.sizeInBytes() - sizeof (String::CharPointerType::CharType);
size_t bytesNeeded = separatorBytes * (size_t) (last - start - 1);
for (int i = start; i < last; ++i)
@@ -358,7 +310,7 @@ String StringArray::joinIntoString (const String& separator, int start, int numb
dest.writeAll (s.getCharPointer());
if (++start < last && separatorBytes > 0)
dest.writeAll (separator.getCharPointer());
dest.writeAll (separator.text);
}
dest.writeNull();
@@ -366,23 +318,22 @@ String StringArray::joinIntoString (const String& separator, int start, int numb
return result;
}
int StringArray::addTokens (const String& text, const bool preserveQuotedStrings)
int StringArray::addTokens (StringRef text, const bool preserveQuotedStrings)
{
return addTokens (text, " \n\r\t", preserveQuotedStrings ? "\"" : "");
}
int StringArray::addTokens (const String& text, const String& breakCharacters, const String& quoteCharacters)
int StringArray::addTokens (StringRef text, StringRef breakCharacters, StringRef quoteCharacters)
{
int num = 0;
String::CharPointerType t (text.getCharPointer());
if (! t.isEmpty())
if (text.isNotEmpty())
{
for (;;)
for (String::CharPointerType t (text.text);;)
{
String::CharPointerType tokenEnd (CharacterFunctions::findEndOfToken (t,
breakCharacters.getCharPointer(),
quoteCharacters.getCharPointer()));
breakCharacters.text,
quoteCharacters.text));
strings.add (String (t, tokenEnd));
++num;
@@ -396,10 +347,10 @@ int StringArray::addTokens (const String& text, const String& breakCharacters, c
return num;
}
int StringArray::addLines (const String& sourceText)
int StringArray::addLines (StringRef sourceText)
{
int numLines = 0;
String::CharPointerType text (sourceText.getCharPointer());
String::CharPointerType text (sourceText.text);
bool finished = text.isEmpty();
while (! finished)
@@ -425,24 +376,23 @@ int StringArray::addLines (const String& sourceText)
return numLines;
}
StringArray StringArray::fromTokens (const String& stringToTokenise,
bool preserveQuotedStrings)
StringArray StringArray::fromTokens (StringRef stringToTokenise, bool preserveQuotedStrings)
{
StringArray s;
s.addTokens (stringToTokenise, preserveQuotedStrings);
return s;
}
StringArray StringArray::fromTokens (const String& stringToTokenise,
const String& breakCharacters,
const String& quoteCharacters)
StringArray StringArray::fromTokens (StringRef stringToTokenise,
StringRef breakCharacters,
StringRef quoteCharacters)
{
StringArray s;
s.addTokens (stringToTokenise, breakCharacters, quoteCharacters);
return s;
}
StringArray StringArray::fromLines (const String& stringToBreakUp)
StringArray StringArray::fromLines (StringRef stringToBreakUp)
{
StringArray s;
s.addLines (stringToBreakUp);
@@ -456,9 +406,7 @@ void StringArray::removeDuplicates (const bool ignoreCase)
{
const String s (strings.getReference(i));
int nextIndex = i + 1;
for (;;)
for (int nextIndex = i + 1;;)
{
nextIndex = indexOf (s, ignoreCase, nextIndex);


+ 22
- 23
source/modules/juce_core/text/juce_StringArray.h View File

@@ -44,10 +44,10 @@ public:
StringArray() noexcept;
/** Creates a copy of another string array */
StringArray (const StringArray& other);
StringArray (const StringArray&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
StringArray (StringArray&& other) noexcept;
StringArray (StringArray&&) noexcept;
#endif
/** Creates an array containing a single string. */
@@ -90,27 +90,27 @@ public:
~StringArray();
/** Copies the contents of another string array into this one */
StringArray& operator= (const StringArray& other);
StringArray& operator= (const StringArray&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
StringArray& operator= (StringArray&& other) noexcept;
StringArray& operator= (StringArray&&) noexcept;
#endif
/** Swaps the contents of this and another StringArray. */
void swapWith (StringArray& other) noexcept;
void swapWith (StringArray&) noexcept;
//==============================================================================
/** Compares two arrays.
Comparisons are case-sensitive.
@returns true only if the other array contains exactly the same strings in the same order
*/
bool operator== (const StringArray& other) const noexcept;
bool operator== (const StringArray&) const noexcept;
/** Compares two arrays.
Comparisons are case-sensitive.
@returns false if the other array contains exactly the same strings in the same order
*/
bool operator!= (const StringArray& other) const noexcept;
bool operator!= (const StringArray&) const noexcept;
//==============================================================================
/** Returns the number of strings in the array */
@@ -153,7 +153,7 @@ public:
@returns true if the string is found inside the array
*/
bool contains (const String& stringToLookFor,
bool contains (StringRef stringToLookFor,
bool ignoreCase = false) const;
/** Searches for a string in the array.
@@ -166,7 +166,7 @@ public:
@returns the index of the first occurrence of the string in this array,
or -1 if it isn't found.
*/
int indexOf (const String& stringToLookFor,
int indexOf (StringRef stringToLookFor,
bool ignoreCase = false,
int startIndex = 0) const;
@@ -214,8 +214,7 @@ public:
@returns the number of tokens added
@see fromTokens
*/
int addTokens (const String& stringToTokenise,
bool preserveQuotedStrings);
int addTokens (StringRef stringToTokenise, bool preserveQuotedStrings);
/** Breaks up a string into tokens and adds them to this array.
@@ -231,9 +230,9 @@ public:
@returns the number of tokens added
@see fromTokens
*/
int addTokens (const String& stringToTokenise,
const String& breakCharacters,
const String& quoteCharacters);
int addTokens (StringRef stringToTokenise,
StringRef breakCharacters,
StringRef quoteCharacters);
/** Breaks up a string into lines and adds them to this array.
@@ -241,7 +240,7 @@ public:
to the array. Line-break characters are omitted from the strings that are added to
the array.
*/
int addLines (const String& stringToBreakUp);
int addLines (StringRef stringToBreakUp);
/** Returns an array containing the tokens in a given string.
@@ -249,7 +248,7 @@ public:
token delimiters, and return these tokens as an array.
@see addTokens
*/
static StringArray fromTokens (const String& stringToTokenise,
static StringArray fromTokens (StringRef stringToTokenise,
bool preserveQuotedStrings);
/** Returns an array containing the tokens in a given string.
@@ -265,9 +264,9 @@ public:
between quotes is not broken up into tokens.
@see addTokens
*/
static StringArray fromTokens (const String& stringToTokenise,
const String& breakCharacters,
const String& quoteCharacters);
static StringArray fromTokens (StringRef stringToTokenise,
StringRef breakCharacters,
StringRef quoteCharacters);
/** Returns an array containing the lines in a given string.
@@ -275,7 +274,7 @@ public:
array containing these lines. Line-break characters are omitted from the strings that
are added to the array.
*/
static StringArray fromLines (const String& stringToBreakUp);
static StringArray fromLines (StringRef stringToBreakUp);
//==============================================================================
/** Removes all elements from the array. */
@@ -295,7 +294,7 @@ public:
This will remove the first occurrence of the given string from the array. The
comparison may be case-insensitive depending on the ignoreCase parameter.
*/
void removeString (const String& stringToRemove,
void removeString (StringRef stringToRemove,
bool ignoreCase = false);
/** Removes a range of elements from the array.
@@ -379,7 +378,7 @@ public:
@param numberOfElements how many elements to join together. If this is less
than zero, all available elements will be used.
*/
String joinIntoString (const String& separatorString,
String joinIntoString (StringRef separatorString,
int startIndex = 0,
int numberOfElements = -1) const;
@@ -410,7 +409,7 @@ public:
private:
//==============================================================================
Array <String> strings;
Array<String> strings;
JUCE_LEAK_DETECTOR (StringArray)
};


+ 3
- 3
source/modules/juce_core/text/juce_StringPairArray.cpp View File

@@ -63,12 +63,12 @@ bool StringPairArray::operator!= (const StringPairArray& other) const
return ! operator== (other);
}
const String& StringPairArray::operator[] (const String& key) const
const String& StringPairArray::operator[] (StringRef key) const
{
return values [keys.indexOf (key, ignoreCase)];
}
String StringPairArray::getValue (const String& key, const String& defaultReturnValue) const
String StringPairArray::getValue (StringRef key, const String& defaultReturnValue) const
{
const int i = keys.indexOf (key, ignoreCase);
@@ -105,7 +105,7 @@ void StringPairArray::clear()
values.clear();
}
void StringPairArray::remove (const String& key)
void StringPairArray::remove (StringRef key)
{
remove (keys.indexOf (key, ignoreCase));
}


+ 3
- 9
source/modules/juce_core/text/juce_StringPairArray.h View File

@@ -77,15 +77,13 @@ public:
@see getValue
*/
const String& operator[] (const String& key) const;
const String& operator[] (StringRef key) const;
/** Finds the value corresponding to a key string.
If no such key is found, this will just return the value provided as a default.
@see operator[]
*/
String getValue (const String& key, const String& defaultReturnValue) const;
String getValue (StringRef, const String& defaultReturnValue) const;
/** Returns a list of all keys in the array. */
@@ -100,14 +98,12 @@ public:
//==============================================================================
/** Adds or amends a key/value pair.
If a value already exists with this key, its value will be overwritten,
otherwise the key/value pair will be added to the array.
*/
void set (const String& key, const String& value);
/** Adds the items from another array to this one.
This is equivalent to using set() to add each of the pairs from the other array.
*/
void addArray (const StringPairArray& other);
@@ -117,13 +113,11 @@ public:
void clear();
/** Removes a string from the array based on its key.
If the key isn't found, nothing will happen.
*/
void remove (const String& key);
void remove (StringRef key);
/** Removes a string from the array based on its index.
If the index is out-of-range, no action will be taken.
*/
void remove (int index);


+ 20
- 21
source/modules/juce_core/text/juce_StringPool.cpp View File

@@ -48,33 +48,32 @@ namespace StringPoolHelpers
strings.insert (start, newString);
return strings.getReference (start).getCharPointer();
}
else
{
const String& startString = strings.getReference (start);
if (startString == newString)
return startString.getCharPointer();
const int halfway = (start + end) >> 1;
const String& startString = strings.getReference (start);
if (halfway == start)
{
if (startString.compare (newString) < 0)
++start;
if (startString == newString)
return startString.getCharPointer();
strings.insert (start, newString);
return strings.getReference (start).getCharPointer();
}
const int halfway = (start + end) >> 1;
const int comp = strings.getReference (halfway).compare (newString);
if (halfway == start)
{
if (startString.compare (newString) < 0)
++start;
if (comp == 0)
return strings.getReference (halfway).getCharPointer();
else if (comp < 0)
start = halfway;
else
end = halfway;
strings.insert (start, newString);
return strings.getReference (start).getCharPointer();
}
const int comp = strings.getReference (halfway).compare (newString);
if (comp == 0)
return strings.getReference (halfway).getCharPointer();
if (comp < 0)
start = halfway;
else
end = halfway;
}
}
}


+ 135
- 0
source/modules/juce_core/text/juce_StringRef.h View File

@@ -0,0 +1,135 @@
/*
==============================================================================
This file is part of the juce_core module of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the juce_core module!
All other JUCE modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.juce.com
==============================================================================
*/
#ifndef JUCE_STRINGREF_H_INCLUDED
#define JUCE_STRINGREF_H_INCLUDED
//==============================================================================
/**
A simple class for holding temporary references to a string literal or String.
Unlike a real String object, the StringRef does not allocate any memory or
take ownership of the strings you give to it - it simply holds a reference to
a string that has been allocated elsewhere.
The main purpose of the class is to be used instead of a const String& as the type
of function arguments where the caller may pass either a string literal or a String
object. This means that when the called uses a string literal, there's no need
for an temporary String object to be allocated, and this cuts down overheads
substantially.
Because the class is simply a wrapper around a pointer, you should always pass
it by value, not by reference.
@code
void myStringFunction1 (const String&);
void myStringFunction2 (StringRef);
myStringFunction1 ("abc"); // Implicitly allocates a temporary String object.
myStringFunction2 ("abc"); // Much faster, as no local allocations are needed.
@endcode
For examples of it in use, see the XmlElement or StringArray classes.
Bear in mind that there are still many cases where it's better to use an argument
which is a const String&. For example if the function stores the string or needs
to internally create a String from the argument, then it's better for the original
argument to already be a String.
@see String
*/
class JUCE_API StringRef
{
public:
/** Creates a StringRef from a raw string literal.
The StringRef object does NOT take ownership or copy this data, so you must
ensure that the data does not change during the lifetime of the StringRef.
Note that this pointer not be null!
*/
StringRef (const char* stringLiteral) noexcept;
/** Creates a StringRef from a raw char pointer.
The StringRef object does NOT take ownership or copy this data, so you must
ensure that the data does not change during the lifetime of the StringRef.
*/
StringRef (String::CharPointerType stringLiteral) noexcept;
/** Creates a StringRef from a String.
The StringRef object does NOT take ownership or copy the data from the String,
so you must ensure that the String is not modified or deleted during the lifetime
of the StringRef.
*/
StringRef (const String& string) noexcept;
/** Creates a StringRef pointer to an empty string. */
StringRef() noexcept;
//==============================================================================
/** Returns a raw pointer to the underlying string data. */
operator const String::CharPointerType::CharType*() const noexcept { return text.getAddress(); }
/** Returns a pointer to the underlying string data as a char pointer object. */
operator String::CharPointerType() const noexcept { return text; }
/** Returns true if the string is empty. */
bool isEmpty() const noexcept { return text.isEmpty(); }
/** Returns true if the string is not empty. */
bool isNotEmpty() const noexcept { return ! text.isEmpty(); }
/** Returns the number of characters in the string. */
int length() const noexcept { return (int) text.length(); }
/** Compares this StringRef with a String. */
bool operator== (const String& s) const noexcept { return text.compare (s.getCharPointer()) == 0; }
/** Compares this StringRef with a String. */
bool operator!= (const String& s) const noexcept { return text.compare (s.getCharPointer()) != 0; }
/** Case-sensitive comparison of two StringRefs. */
bool operator== (StringRef s) const noexcept { return text.compare (s.text) == 0; }
/** Case-sensitive comparison of two StringRefs. */
bool operator!= (StringRef s) const noexcept { return text.compare (s.text) != 0; }
//==============================================================================
/** The text that is referenced. */
String::CharPointerType text;
#if JUCE_STRING_UTF_TYPE != 8 && ! defined (DOXYGEN)
// Sorry, non-UTF8 people, you're unable to take advantage of StringRef, because
// you've chosen a character encoding that doesn't match C++ string literals.
String stringCopy;
#endif
};
//==============================================================================
/** Case-sensitive comparison of two strings. */
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, StringRef string2) noexcept;
/** Case-sensitive comparison of two strings. */
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, StringRef string2) noexcept;
#if JUCE_STRING_UTF_TYPE != 8 && ! defined (DOXYGEN)
inline String operator+ (String s1, StringRef s2) { return s1 += String (s2.text); }
#endif
#endif // JUCE_STRINGREF_H_INCLUDED

+ 6
- 5
source/modules/juce_core/text/juce_TextDiff.cpp View File

@@ -191,10 +191,9 @@ class DiffTests : public UnitTest
public:
DiffTests() : UnitTest ("TextDiff class") {}
static String createString()
static String createString (Random& r)
{
juce_wchar buffer[50] = { 0 };
Random r;
for (int i = r.nextInt (49); --i >= 0;)
{
@@ -224,6 +223,8 @@ public:
{
beginTest ("TextDiff");
Random r = getRandom();
testDiff (String::empty, String::empty);
testDiff ("x", String::empty);
testDiff (String::empty, "x");
@@ -234,9 +235,9 @@ public:
for (int i = 5000; --i >= 0;)
{
String s (createString());
testDiff (s, createString());
testDiff (s + createString(), s + createString());
String s (createString (r));
testDiff (s, createString (r));
testDiff (s + createString (r), s + createString (r));
}
}
};


+ 6
- 6
source/modules/juce_core/threads/juce_CriticalSection.h View File

@@ -103,16 +103,16 @@ public:
private:
//==============================================================================
#if JUCE_WINDOWS
// To avoid including windows.h in the public JUCE headers, we'll just allocate a
// block of memory here that's big enough to be used internally as a windows critical
// section structure.
// To avoid including windows.h in the public JUCE headers, we'll just allocate
// a block of memory here that's big enough to be used internally as a windows
// CRITICAL_SECTION structure.
#if JUCE_64BIT
uint8 internal [44];
uint8 lock[44];
#else
uint8 internal [24];
uint8 lock[24];
#endif
#else
mutable pthread_mutex_t internal;
mutable pthread_mutex_t lock;
#endif
JUCE_DECLARE_NON_COPYABLE (CriticalSection)


+ 2
- 2
source/modules/juce_core/threads/juce_Process.h View File

@@ -36,7 +36,7 @@
This contains methods for controlling the current application at the
process-level.
@see Thread, JUCEApplication
@see Thread, JUCEApplicationBase
*/
class JUCE_API Process
{
@@ -63,7 +63,7 @@ public:
immediately - it's intended only for use only when something goes
horribly wrong.
@see JUCEApplication::quit
@see JUCEApplicationBase::quit
*/
static void JUCE_CALLTYPE terminate();


+ 4
- 7
source/modules/juce_core/threads/juce_ReadWriteLock.h View File

@@ -59,18 +59,15 @@ public:
ReadWriteLock() noexcept;
/** Destructor.
If the object is deleted whilst locked, any subsequent behaviour
is unpredictable.
If the object is deleted whilst locked, any subsequent behaviour is undefined.
*/
~ReadWriteLock() noexcept;
//==============================================================================
/** Locks this object for reading.
Multiple threads can simulaneously lock the object for reading, but if another
thread has it locked for writing, then this will block until it releases the
lock.
Multiple threads can simultaneously lock the object for reading, but if another
thread has it locked for writing, then this will block until it releases the lock.
@see exitRead, ScopedReadLock
*/
@@ -78,7 +75,7 @@ public:
/** Tries to lock this object for reading.
Multiple threads can simulaneously lock the object for reading, but if another
Multiple threads can simultaneously lock the object for reading, but if another
thread has it locked for writing, then this will fail and return false.
@returns true if the lock is successfully gained.


+ 1
- 2
source/modules/juce_core/threads/juce_WaitableEvent.h View File

@@ -96,7 +96,6 @@ public:
//==============================================================================
/** Resets the event to an unsignalled state.
If it's not already signalled, this does nothing.
*/
void reset() const noexcept;
@@ -105,7 +104,7 @@ public:
private:
//==============================================================================
#if JUCE_WINDOWS
void* internal;
void* handle;
#else
mutable pthread_cond_t condition;
mutable pthread_mutex_t mutex;


+ 31
- 8
source/modules/juce_core/unit_tests/juce_UnitTest.cpp View File

@@ -26,8 +26,8 @@
==============================================================================
*/
UnitTest::UnitTest (const String& name_)
: name (name_), runner (nullptr)
UnitTest::UnitTest (const String& nm)
: name (nm), runner (nullptr)
{
getAllTests().add (this);
}
@@ -46,10 +46,10 @@ Array<UnitTest*>& UnitTest::getAllTests()
void UnitTest::initialise() {}
void UnitTest::shutdown() {}
void UnitTest::performTest (UnitTestRunner* const runner_)
void UnitTest::performTest (UnitTestRunner* const newRunner)
{
jassert (runner_ != nullptr);
runner = runner_;
jassert (newRunner != nullptr);
runner = newRunner;
initialise();
runTest();
@@ -58,22 +58,39 @@ void UnitTest::performTest (UnitTestRunner* const runner_)
void UnitTest::logMessage (const String& message)
{
// This method's only valid while the test is being run!
jassert (runner != nullptr);
runner->logMessage (message);
}
void UnitTest::beginTest (const String& testName)
{
// This method's only valid while the test is being run!
jassert (runner != nullptr);
runner->beginNewTest (this, testName);
}
void UnitTest::expect (const bool result, const String& failureMessage)
{
// This method's only valid while the test is being run!
jassert (runner != nullptr);
if (result)
runner->addPass();
else
runner->addFail (failureMessage);
}
Random UnitTest::getRandom() const
{
// This method's only valid while the test is being run!
jassert (runner != nullptr);
return runner->randomForTest;
}
//==============================================================================
UnitTestRunner::UnitTestRunner()
: currentTest (nullptr),
@@ -110,11 +127,17 @@ void UnitTestRunner::resultsUpdated()
{
}
void UnitTestRunner::runTests (const Array<UnitTest*>& tests)
void UnitTestRunner::runTests (const Array<UnitTest*>& tests, int64 randomSeed)
{
results.clear();
resultsUpdated();
if (randomSeed == 0)
randomSeed = Random().nextInt (0x7ffffff);
randomForTest = Random (randomSeed);
logMessage ("Random seed: 0x" + String::toHexString (randomSeed));
for (int i = 0; i < tests.size(); ++i)
{
if (shouldAbortTests())
@@ -133,9 +156,9 @@ void UnitTestRunner::runTests (const Array<UnitTest*>& tests)
endTest();
}
void UnitTestRunner::runAllTests()
void UnitTestRunner::runAllTests (int64 randomSeed)
{
runTests (UnitTest::getAllTests());
runTests (UnitTest::getAllTests(), randomSeed);
}
void UnitTestRunner::logMessage (const String& message)


+ 25
- 2
source/modules/juce_core/unit_tests/juce_UnitTest.h View File

@@ -163,6 +163,22 @@ public:
*/
void logMessage (const String& message);
/** Returns a shared RNG that all unit tests should use.
If a test needs random numbers, it's important that when an error is found, the
exact circumstances can be re-created in order to re-test the problem, by
repeating the test with the same random seed value.
To make this possible, the UnitTestRunner class creates a master seed value
for the run, writes this number to the log, and then this method returns a
Random object based on that seed. All tests should only use this method to
create any Random objects that they need.
Note that this method will return an identical object each time it's called
for a given run, so if you need several different Random objects, the best
way to do that is to call Random::combineSeed() on the result to permute it
with a constant value.
*/
Random getRandom() const;
private:
//==============================================================================
const String name;
@@ -198,13 +214,19 @@ public:
The tests are performed in order, and the results are logged. To run all the
registered UnitTest objects that exist, use runAllTests().
If you want to run the tests with a predetermined seed, you can pass that into
the randomSeed argument, or pass 0 to have a randomly-generated seed chosen.
*/
void runTests (const Array<UnitTest*>& tests);
void runTests (const Array<UnitTest*>& tests, int64 randomSeed = 0);
/** Runs all the UnitTest objects that currently exist.
This calls runTests() for all the objects listed in UnitTest::getAllTests().
If you want to run the tests with a predetermined seed, you can pass that into
the randomSeed argument, or pass 0 to have a randomly-generated seed chosen.
*/
void runAllTests();
void runAllTests (int64 randomSeed = 0);
/** Sets a flag to indicate whether an assertion should be triggered if a test fails.
This is true by default.
@@ -274,6 +296,7 @@ private:
String currentSubCategory;
OwnedArray <TestResult, CriticalSection> results;
bool assertOnFailure, logPasses;
Random randomForTest;
void beginNewTest (UnitTest* test, const String& subCategory);
void endTest();


+ 4
- 2
source/modules/juce_core/xml/juce_XmlDocument.cpp View File

@@ -312,7 +312,8 @@ void XmlDocument::skipNextWhiteSpace()
input += closeComment + 3;
continue;
}
else if (input[1] == '?')
if (input[1] == '?')
{
input += 2;
const int closeBracket = input.indexOf (CharPointer_ASCII ("?>"));
@@ -515,7 +516,8 @@ void XmlDocument::readChildElements (XmlElement* parent)
break;
}
else if (c1 == '!' && CharacterFunctions::compareUpTo (input + 2, CharPointer_ASCII ("[CDATA["), 7) == 0)
if (c1 == '!' && CharacterFunctions::compareUpTo (input + 2, CharPointer_ASCII ("[CDATA["), 7) == 0)
{
input += 9;
const String::CharPointerType inputStart (input);


+ 66
- 69
source/modules/juce_core/xml/juce_XmlElement.cpp View File

@@ -42,7 +42,7 @@ XmlElement::XmlAttributeNode::XmlAttributeNode (const String& n, const String& v
#endif
}
inline bool XmlElement::XmlAttributeNode::hasName (const String& nameToMatch) const noexcept
bool XmlElement::XmlAttributeNode::hasName (StringRef nameToMatch) const noexcept
{
return name.equalsIgnoreCase (nameToMatch);
}
@@ -74,9 +74,7 @@ XmlElement& XmlElement::operator= (const XmlElement& other)
{
removeAllAttributes();
deleteAllChildElements();
tagName = other.tagName;
copyChildrenAndAttributesFrom (other);
}
@@ -85,10 +83,10 @@ XmlElement& XmlElement::operator= (const XmlElement& other)
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
XmlElement::XmlElement (XmlElement&& other) noexcept
: nextListItem (static_cast <LinkedListPointer <XmlElement>&&> (other.nextListItem)),
firstChildElement (static_cast <LinkedListPointer <XmlElement>&&> (other.firstChildElement)),
attributes (static_cast <LinkedListPointer <XmlAttributeNode>&&> (other.attributes)),
tagName (static_cast <String&&> (other.tagName))
: nextListItem (static_cast<LinkedListPointer<XmlElement>&&> (other.nextListItem)),
firstChildElement (static_cast<LinkedListPointer<XmlElement>&&> (other.firstChildElement)),
attributes (static_cast<LinkedListPointer<XmlAttributeNode>&&> (other.attributes)),
tagName (static_cast<String&&> (other.tagName))
{
}
@@ -99,10 +97,10 @@ XmlElement& XmlElement::operator= (XmlElement&& other) noexcept
removeAllAttributes();
deleteAllChildElements();
nextListItem = static_cast <LinkedListPointer <XmlElement>&&> (other.nextListItem);
firstChildElement = static_cast <LinkedListPointer <XmlElement>&&> (other.firstChildElement);
attributes = static_cast <LinkedListPointer <XmlAttributeNode>&&> (other.attributes);
tagName = static_cast <String&&> (other.tagName);
nextListItem = static_cast<LinkedListPointer<XmlElement>&&> (other.nextListItem);
firstChildElement = static_cast<LinkedListPointer<XmlElement>&&> (other.firstChildElement);
attributes = static_cast<LinkedListPointer<XmlAttributeNode>&&> (other.attributes);
tagName = static_cast<String&&> (other.tagName);
return *this;
}
@@ -163,8 +161,8 @@ namespace XmlOutputFunctions
static bool isLegalXmlChar (const uint32 c) noexcept
{
static const unsigned char legalChars[] = { 0, 0, 0, 0, 187, 255, 255, 175, 255, 255, 255, 191, 254, 255, 255, 127 };
static const unsigned char legalChars[] = { 0, 0, 0, 0, 187, 255, 255, 175, 255,
255, 255, 191, 254, 255, 255, 127 };
return c < sizeof (legalChars) * 8
&& (legalChars [c >> 3] & (1 << (c & 7))) != 0;
}
@@ -297,10 +295,10 @@ void XmlElement::writeElementAsText (OutputStream& outputStream,
}
}
String XmlElement::createDocument (const String& dtdToUse,
String XmlElement::createDocument (StringRef dtdToUse,
const bool allOnOneLine,
const bool includeXmlHeader,
const String& encodingType,
StringRef encodingType,
const int lineWrapLength) const
{
MemoryOutputStream mem (2048);
@@ -310,10 +308,10 @@ String XmlElement::createDocument (const String& dtdToUse,
}
void XmlElement::writeToStream (OutputStream& output,
const String& dtdToUse,
StringRef dtdToUse,
const bool allOnOneLine,
const bool includeXmlHeader,
const String& encodingType,
StringRef encodingType,
const int lineWrapLength) const
{
using namespace XmlOutputFunctions;
@@ -345,8 +343,8 @@ void XmlElement::writeToStream (OutputStream& output,
}
bool XmlElement::writeToFile (const File& file,
const String& dtdToUse,
const String& encodingType,
StringRef dtdToUse,
StringRef encodingType,
const int lineWrapLength) const
{
TemporaryFile tempFile (file);
@@ -364,7 +362,7 @@ bool XmlElement::writeToFile (const File& file,
}
//==============================================================================
bool XmlElement::hasTagName (const String& possibleTagName) const noexcept
bool XmlElement::hasTagName (StringRef possibleTagName) const noexcept
{
const bool matches = tagName.equalsIgnoreCase (possibleTagName);
@@ -385,12 +383,12 @@ String XmlElement::getTagNameWithoutNamespace() const
return tagName.fromLastOccurrenceOf (":", false, false);
}
bool XmlElement::hasTagNameIgnoringNamespace (const String& possibleTagName) const
bool XmlElement::hasTagNameIgnoringNamespace (StringRef possibleTagName) const
{
return hasTagName (possibleTagName) || getTagNameWithoutNamespace() == possibleTagName;
}
XmlElement* XmlElement::getNextElementWithTagName (const String& requiredTagName) const
XmlElement* XmlElement::getNextElementWithTagName (StringRef requiredTagName) const
{
XmlElement* e = nextListItem;
@@ -408,89 +406,90 @@ int XmlElement::getNumAttributes() const noexcept
const String& XmlElement::getAttributeName (const int index) const noexcept
{
const XmlAttributeNode* const att = attributes [index];
return att != nullptr ? att->name : String::empty;
if (const XmlAttributeNode* const att = attributes [index])
return att->name;
return String::empty;
}
const String& XmlElement::getAttributeValue (const int index) const noexcept
{
const XmlAttributeNode* const att = attributes [index];
return att != nullptr ? att->value : String::empty;
if (const XmlAttributeNode* const att = attributes [index])
return att->value;
return String::empty;
}
bool XmlElement::hasAttribute (const String& attributeName) const noexcept
XmlElement::XmlAttributeNode* XmlElement::getAttribute (StringRef attributeName) const noexcept
{
for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
for (XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
if (att->hasName (attributeName))
return true;
return att;
return false;
return nullptr;
}
bool XmlElement::hasAttribute (StringRef attributeName) const noexcept
{
return getAttribute (attributeName) != nullptr;
}
//==============================================================================
const String& XmlElement::getStringAttribute (const String& attributeName) const noexcept
const String& XmlElement::getStringAttribute (StringRef attributeName) const noexcept
{
for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value;
if (const XmlAttributeNode* att = getAttribute (attributeName))
return att->value;
return String::empty;
}
String XmlElement::getStringAttribute (const String& attributeName, const String& defaultReturnValue) const
String XmlElement::getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value;
if (const XmlAttributeNode* att = getAttribute (attributeName))
return att->value;
return defaultReturnValue;
}
int XmlElement::getIntAttribute (const String& attributeName, const int defaultReturnValue) const
int XmlElement::getIntAttribute (StringRef attributeName, const int defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value.getIntValue();
if (const XmlAttributeNode* att = getAttribute (attributeName))
return att->value.getIntValue();
return defaultReturnValue;
}
double XmlElement::getDoubleAttribute (const String& attributeName, const double defaultReturnValue) const
double XmlElement::getDoubleAttribute (StringRef attributeName, const double defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value.getDoubleValue();
if (const XmlAttributeNode* att = getAttribute (attributeName))
return att->value.getDoubleValue();
return defaultReturnValue;
}
bool XmlElement::getBoolAttribute (const String& attributeName, const bool defaultReturnValue) const
bool XmlElement::getBoolAttribute (StringRef attributeName, const bool defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
if (const XmlAttributeNode* att = getAttribute (attributeName))
{
if (att->hasName (attributeName))
{
const juce_wchar firstChar = *(att->value.getCharPointer().findEndOfWhitespace());
const juce_wchar firstChar = *(att->value.getCharPointer().findEndOfWhitespace());
return firstChar == '1'
|| firstChar == 't'
|| firstChar == 'y'
|| firstChar == 'T'
|| firstChar == 'Y';
}
return firstChar == '1'
|| firstChar == 't'
|| firstChar == 'y'
|| firstChar == 'T'
|| firstChar == 'Y';
}
return defaultReturnValue;
}
bool XmlElement::compareAttribute (const String& attributeName,
const String& stringToCompareAgainst,
bool XmlElement::compareAttribute (StringRef attributeName,
StringRef stringToCompareAgainst,
const bool ignoreCase) const noexcept
{
for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
if (att->hasName (attributeName))
return ignoreCase ? att->value.equalsIgnoreCase (stringToCompareAgainst)
: att->value == stringToCompareAgainst;
if (const XmlAttributeNode* att = getAttribute (attributeName))
return ignoreCase ? att->value.equalsIgnoreCase (stringToCompareAgainst)
: att->value == stringToCompareAgainst;
return false;
}
@@ -561,7 +560,7 @@ XmlElement* XmlElement::getChildElement (const int index) const noexcept
return firstChildElement [index].get();
}
XmlElement* XmlElement::getChildByName (const String& childName) const noexcept
XmlElement* XmlElement::getChildByName (StringRef childName) const noexcept
{
for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem)
if (child->hasTagName (childName))
@@ -576,8 +575,7 @@ void XmlElement::addChildElement (XmlElement* const newNode) noexcept
firstChildElement.append (newNode);
}
void XmlElement::insertChildElement (XmlElement* const newNode,
int indexToInsertAt) noexcept
void XmlElement::insertChildElement (XmlElement* const newNode, int indexToInsertAt) noexcept
{
if (newNode != nullptr)
{
@@ -700,7 +698,7 @@ void XmlElement::deleteAllChildElements() noexcept
firstChildElement.deleteAll();
}
void XmlElement::deleteAllChildElementsWithTagName (const String& name) noexcept
void XmlElement::deleteAllChildElementsWithTagName (StringRef name) noexcept
{
for (XmlElement* child = firstChildElement; child != nullptr;)
{
@@ -791,8 +789,7 @@ String XmlElement::getAllSubText() const
return mem.toUTF8();
}
String XmlElement::getChildElementAllSubText (const String& childTagName,
const String& defaultReturnValue) const
String XmlElement::getChildElementAllSubText (StringRef childTagName, const String& defaultReturnValue) const
{
if (const XmlElement* const child = getChildByName (childTagName))
return child->getAllSubText();


+ 28
- 43
source/modules/juce_core/xml/juce_XmlElement.h View File

@@ -193,10 +193,10 @@ public:
determines how lists of attributes get broken up
@see writeToStream, writeToFile
*/
String createDocument (const String& dtdToUse,
String createDocument (StringRef dtdToUse,
bool allOnOneLine = false,
bool includeXmlHeader = true,
const String& encodingType = "UTF-8",
StringRef encodingType = "UTF-8",
int lineWrapLength = 60) const;
/** Writes the document to a stream as UTF-8.
@@ -215,10 +215,10 @@ public:
@see writeToFile, createDocument
*/
void writeToStream (OutputStream& output,
const String& dtdToUse,
StringRef dtdToUse,
bool allOnOneLine = false,
bool includeXmlHeader = true,
const String& encodingType = "UTF-8",
StringRef encodingType = "UTF-8",
int lineWrapLength = 60) const;
/** Writes the element to a file as an XML document.
@@ -241,8 +241,8 @@ public:
@see createDocument
*/
bool writeToFile (const File& destinationFile,
const String& dtdToUse,
const String& encodingType = "UTF-8",
StringRef dtdToUse,
StringRef encodingType = "UTF-8",
int lineWrapLength = 60) const;
//==============================================================================
@@ -250,7 +250,7 @@ public:
E.g. for an element such as \<MOOSE legs="4" antlers="2">, this would return "MOOSE".
@see hasTagName
*/
inline const String& getTagName() const noexcept { return tagName; }
const String& getTagName() const noexcept { return tagName; }
/** Returns the namespace portion of the tag-name, or an empty string if none is specified. */
String getNamespace() const;
@@ -262,13 +262,13 @@ public:
@param possibleTagName the tag name you're comparing it with
@see getTagName
*/
bool hasTagName (const String& possibleTagName) const noexcept;
bool hasTagName (StringRef possibleTagName) const noexcept;
/** Tests whether this element has a particular tag name, ignoring any XML namespace prefix.
So a test for e.g. "xyz" will return true for "xyz" and also "foo:xyz", "bar::xyz", etc.
@see getTagName
*/
bool hasTagNameIgnoringNamespace (const String& possibleTagName) const;
bool hasTagNameIgnoringNamespace (StringRef possibleTagName) const;
//==============================================================================
/** Returns the number of XML attributes this element contains.
@@ -300,13 +300,13 @@ public:
// Attribute-handling methods..
/** Checks whether the element contains an attribute with a certain name. */
bool hasAttribute (const String& attributeName) const noexcept;
bool hasAttribute (StringRef attributeName) const noexcept;
/** Returns the value of a named attribute.
@param attributeName the name of the attribute to look up
*/
const String& getStringAttribute (const String& attributeName) const noexcept;
const String& getStringAttribute (StringRef attributeName) const noexcept;
/** Returns the value of a named attribute.
@@ -314,8 +314,7 @@ public:
@param defaultReturnValue a value to return if the element doesn't have an attribute
with this name
*/
String getStringAttribute (const String& attributeName,
const String& defaultReturnValue) const;
String getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const;
/** Compares the value of a named attribute with a value passed-in.
@@ -325,8 +324,8 @@ public:
@returns true if the value of the attribute is the same as the string passed-in;
false if it's different (or if no such attribute exists)
*/
bool compareAttribute (const String& attributeName,
const String& stringToCompareAgainst,
bool compareAttribute (StringRef attributeName,
StringRef stringToCompareAgainst,
bool ignoreCase = false) const noexcept;
/** Returns the value of a named attribute as an integer.
@@ -339,8 +338,7 @@ public:
with this name
@see setAttribute
*/
int getIntAttribute (const String& attributeName,
int defaultReturnValue = 0) const;
int getIntAttribute (StringRef attributeName, int defaultReturnValue = 0) const;
/** Returns the value of a named attribute as floating-point.
@@ -352,8 +350,7 @@ public:
with this name
@see setAttribute
*/
double getDoubleAttribute (const String& attributeName,
double defaultReturnValue = 0.0) const;
double getDoubleAttribute (StringRef attributeName, double defaultReturnValue = 0.0) const;
/** Returns the value of a named attribute as a boolean.
@@ -365,8 +362,7 @@ public:
@param defaultReturnValue a value to return if the element doesn't have an attribute
with this name
*/
bool getBoolAttribute (const String& attributeName,
bool defaultReturnValue = false) const;
bool getBoolAttribute (StringRef attributeName, bool defaultReturnValue = false) const;
/** Adds a named attribute to the element.
@@ -381,8 +377,7 @@ public:
@param newValue the value to set it to
@see removeAttribute
*/
void setAttribute (const String& attributeName,
const String& newValue);
void setAttribute (const String& attributeName, const String& newValue);
/** Adds a named attribute to the element, setting it to an integer value.
@@ -396,8 +391,7 @@ public:
@param attributeName the name of the attribute to set
@param newValue the value to set it to
*/
void setAttribute (const String& attributeName,
int newValue);
void setAttribute (const String& attributeName, int newValue);
/** Adds a named attribute to the element, setting it to a floating-point value.
@@ -411,8 +405,7 @@ public:
@param attributeName the name of the attribute to set
@param newValue the value to set it to
*/
void setAttribute (const String& attributeName,
double newValue);
void setAttribute (const String& attributeName, double newValue);
/** Removes a named attribute from the element.
@@ -421,17 +414,14 @@ public:
*/
void removeAttribute (const String& attributeName) noexcept;
/** Removes all attributes from this element.
*/
/** Removes all attributes from this element. */
void removeAllAttributes() noexcept;
//==============================================================================
// Child element methods..
/** Returns the first of this element's sub-elements.
see getNextElement() for an example of how to iterate the sub-elements.
@see forEachXmlChildElement
*/
XmlElement* getFirstChildElement() const noexcept { return firstChildElement; }
@@ -472,10 +462,9 @@ public:
@see getNextElement, forEachXmlChildElementWithTagName
*/
XmlElement* getNextElementWithTagName (const String& requiredTagName) const;
XmlElement* getNextElementWithTagName (StringRef requiredTagName) const;
/** Returns the number of sub-elements in this element.
@see getChildElement
*/
int getNumChildElements() const noexcept;
@@ -496,7 +485,7 @@ public:
@returns the first element with this tag name, or nullptr if none is found
@see getNextElement, isTextElement, getChildElement
*/
XmlElement* getChildByName (const String& tagNameToLookFor) const noexcept;
XmlElement* getChildByName (StringRef tagNameToLookFor) const noexcept;
//==============================================================================
/** Appends an element to this element's list of children.
@@ -560,16 +549,14 @@ public:
bool shouldDeleteTheChild) noexcept;
/** Deletes all the child elements in the element.
@see removeChildElement, deleteAllChildElementsWithTagName
*/
void deleteAllChildElements() noexcept;
/** Deletes all the child elements with a given tag name.
@see removeChildElement
*/
void deleteAllChildElementsWithTagName (const String& tagName) noexcept;
void deleteAllChildElementsWithTagName (StringRef tagName) noexcept;
/** Returns true if the given element is a child of this one. */
bool containsChildElement (const XmlElement* possibleChild) const noexcept;
@@ -676,23 +663,20 @@ public:
@see getAllSubText
*/
String getChildElementAllSubText (const String& childTagName,
String getChildElementAllSubText (StringRef childTagName,
const String& defaultReturnValue) const;
/** Appends a section of text to this element.
@see isTextElement, getText, getAllSubText
*/
void addTextElement (const String& text);
/** Removes all the text elements from this element.
@see isTextElement, getText, getAllSubText, addTextElement
*/
void deleteAllTextElements() noexcept;
/** Creates a text element that can be added to a parent element.
*/
/** Creates a text element that can be added to a parent element. */
static XmlElement* createTextElement (const String& text);
//==============================================================================
@@ -705,7 +689,7 @@ private:
LinkedListPointer<XmlAttributeNode> nextListItem;
String name, value;
bool hasName (const String&) const noexcept;
bool hasName (StringRef) const noexcept;
private:
XmlAttributeNode& operator= (const XmlAttributeNode&);
@@ -726,6 +710,7 @@ private:
void writeElementAsText (OutputStream&, int indentationLevel, int lineWrapLength) const;
void getChildElementsAsArray (XmlElement**) const noexcept;
void reorderChildElements (XmlElement**, int) noexcept;
XmlAttributeNode* getAttribute (StringRef) const noexcept;
JUCE_LEAK_DETECTOR (XmlElement)
};


+ 1
- 1
source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp View File

@@ -169,7 +169,7 @@ public:
void runTest()
{
beginTest ("GZIP");
Random rng;
Random rng = getRandom();
for (int i = 100; --i >= 0;)
{


+ 4
- 0
source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp View File

@@ -66,6 +66,10 @@ namespace zlibNamespace
#undef Byte
#undef fdopen
#undef local
#undef Freq
#undef Code
#undef Dad
#undef Len
#if JUCE_CLANG
#pragma clang diagnostic pop


Loading…
Cancel
Save