Browse Source

Update juce-core

tags/1.9.4
falkTX 11 years ago
parent
commit
4dd1539f1c
78 changed files with 950 additions and 444 deletions
  1. +4
    -1
      data/copy-juce-carla
  2. +2
    -1
      source/modules/juce_core/containers/juce_Array.h
  3. +13
    -6
      source/modules/juce_core/containers/juce_DynamicObject.cpp
  4. +5
    -3
      source/modules/juce_core/containers/juce_DynamicObject.h
  5. +10
    -10
      source/modules/juce_core/containers/juce_NamedValueSet.cpp
  6. +9
    -9
      source/modules/juce_core/containers/juce_NamedValueSet.h
  7. +43
    -50
      source/modules/juce_core/containers/juce_OwnedArray.h
  8. +2
    -2
      source/modules/juce_core/containers/juce_PropertySet.cpp
  9. +3
    -3
      source/modules/juce_core/containers/juce_PropertySet.h
  10. +6
    -0
      source/modules/juce_core/containers/juce_Variant.cpp
  11. +5
    -5
      source/modules/juce_core/files/juce_DirectoryIterator.h
  12. +6
    -6
      source/modules/juce_core/files/juce_File.cpp
  13. +1
    -1
      source/modules/juce_core/files/juce_File.h
  14. +41
    -0
      source/modules/juce_core/files/juce_FileFilter.cpp
  15. +77
    -0
      source/modules/juce_core/files/juce_FileFilter.h
  16. +1
    -1
      source/modules/juce_core/files/juce_FileSearchPath.h
  17. +2
    -2
      source/modules/juce_core/files/juce_TemporaryFile.cpp
  18. +1
    -1
      source/modules/juce_core/files/juce_TemporaryFile.h
  19. +77
    -0
      source/modules/juce_core/files/juce_WildcardFileFilter.cpp
  20. +86
    -0
      source/modules/juce_core/files/juce_WildcardFileFilter.h
  21. +19
    -54
      source/modules/juce_core/javascript/juce_JSON.cpp
  22. +16
    -1
      source/modules/juce_core/javascript/juce_JSON.h
  23. +37
    -20
      source/modules/juce_core/javascript/juce_Javascript.cpp
  24. +1
    -2
      source/modules/juce_core/javascript/juce_Javascript.h
  25. +2
    -0
      source/modules/juce_core/juce_core.cpp
  26. +2
    -0
      source/modules/juce_core/juce_core.h
  27. +1
    -1
      source/modules/juce_core/maths/juce_BigInteger.cpp
  28. +30
    -31
      source/modules/juce_core/maths/juce_BigInteger.h
  29. +5
    -7
      source/modules/juce_core/maths/juce_Expression.cpp
  30. +9
    -9
      source/modules/juce_core/maths/juce_Expression.h
  31. +17
    -14
      source/modules/juce_core/memory/juce_Atomic.h
  32. +0
    -1
      source/modules/juce_core/misc/juce_Uuid.cpp
  33. +1
    -1
      source/modules/juce_core/native/juce_android_Files.cpp
  34. +4
    -0
      source/modules/juce_core/native/juce_android_Network.cpp
  35. +5
    -0
      source/modules/juce_core/native/juce_android_SystemStats.cpp
  36. +3
    -3
      source/modules/juce_core/native/juce_linux_Files.cpp
  37. +3
    -3
      source/modules/juce_core/native/juce_linux_Network.cpp
  38. +8
    -3
      source/modules/juce_core/native/juce_linux_SystemStats.cpp
  39. +3
    -3
      source/modules/juce_core/native/juce_mac_Files.mm
  40. +1
    -1
      source/modules/juce_core/native/juce_mac_Strings.mm
  41. +12
    -3
      source/modules/juce_core/native/juce_mac_SystemStats.mm
  42. +6
    -1
      source/modules/juce_core/native/juce_posix_NamedPipe.cpp
  43. +1
    -1
      source/modules/juce_core/native/juce_posix_SharedCode.h
  44. +4
    -2
      source/modules/juce_core/native/juce_win32_Files.cpp
  45. +5
    -0
      source/modules/juce_core/native/juce_win32_SystemStats.cpp
  46. +1
    -1
      source/modules/juce_core/network/juce_IPAddress.cpp
  47. +4
    -4
      source/modules/juce_core/network/juce_MACAddress.h
  48. +2
    -2
      source/modules/juce_core/network/juce_Socket.cpp
  49. +1
    -1
      source/modules/juce_core/network/juce_Socket.h
  50. +4
    -4
      source/modules/juce_core/network/juce_URL.cpp
  51. +1
    -1
      source/modules/juce_core/network/juce_URL.h
  52. +3
    -3
      source/modules/juce_core/system/juce_StandardHeader.h
  53. +7
    -2
      source/modules/juce_core/system/juce_SystemStats.h
  54. +1
    -1
      source/modules/juce_core/text/juce_CharPointer_UTF16.h
  55. +1
    -1
      source/modules/juce_core/text/juce_CharPointer_UTF32.h
  56. +3
    -10
      source/modules/juce_core/text/juce_CharPointer_UTF8.h
  57. +2
    -2
      source/modules/juce_core/text/juce_CharacterFunctions.h
  58. +30
    -2
      source/modules/juce_core/text/juce_LocalisedStrings.cpp
  59. +14
    -5
      source/modules/juce_core/text/juce_LocalisedStrings.h
  60. +62
    -15
      source/modules/juce_core/text/juce_String.cpp
  61. +39
    -24
      source/modules/juce_core/text/juce_String.h
  62. +1
    -1
      source/modules/juce_core/text/juce_StringArray.cpp
  63. +4
    -5
      source/modules/juce_core/text/juce_StringArray.h
  64. +5
    -0
      source/modules/juce_core/text/juce_StringPairArray.cpp
  65. +2
    -0
      source/modules/juce_core/text/juce_StringPairArray.h
  66. +3
    -3
      source/modules/juce_core/text/juce_StringPool.cpp
  67. +1
    -1
      source/modules/juce_core/threads/juce_Thread.cpp
  68. +2
    -2
      source/modules/juce_core/threads/juce_ThreadPool.h
  69. +76
    -40
      source/modules/juce_core/time/juce_PerformanceCounter.cpp
  70. +29
    -8
      source/modules/juce_core/time/juce_PerformanceCounter.h
  71. +1
    -1
      source/modules/juce_core/time/juce_Time.cpp
  72. +1
    -1
      source/modules/juce_core/xml/juce_XmlDocument.cpp
  73. +0
    -7
      source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp
  74. +36
    -25
      source/modules/juce_core/zip/juce_ZipFile.cpp
  75. +15
    -0
      source/modules/juce_core/zip/juce_ZipFile.h
  76. +8
    -8
      source/modules/juce_core/zip/zlib/crc32.c
  77. +1
    -1
      source/modules/juce_core/zip/zlib/inflate.c
  78. +1
    -1
      source/modules/juce_core/zip/zlib/trees.c

+ 4
- 1
data/copy-juce-carla View File

@@ -1,9 +1,12 @@
#!/bin/bash #!/bin/bash


set -e

JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/DISTRHO/libs/juce/source/modules/" JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/DISTRHO/libs/juce/source/modules/"
CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/Carla/source/modules" CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/Carla/source/modules"


MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics")
# MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics")
MODULES=("juce_core")


for M in $MODULES; do for M in $MODULES; do
echo $M; echo $M;


+ 2
- 1
source/modules/juce_core/containers/juce_Array.h View File

@@ -40,7 +40,7 @@
do so, the class must fulfil these requirements: do so, the class must fulfil these requirements:
- it must have a copy constructor and assignment operator - it must have a copy constructor and assignment operator
- it must be able to be relocated in memory by a memcpy without this causing any problems - so - it must be able to be relocated in memory by a memcpy without this causing any problems - so
objects whose functionality relies on external pointers or references to themselves can be used.
objects whose functionality relies on external pointers or references to themselves can not be used.
You can of course have an array of pointers to any kind of object, e.g. Array <MyClass*>, but if You can of course have an array of pointers to any kind of object, e.g. Array <MyClass*>, but if
you do this, the array doesn't take any ownership of the objects - see the OwnedArray class or the you do this, the array doesn't take any ownership of the objects - see the OwnedArray class or the
@@ -143,6 +143,7 @@ public:
Array& operator= (Array&& other) noexcept Array& operator= (Array&& other) noexcept
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
deleteAllElements();
data = static_cast<ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&&> (other.data); data = static_cast<ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&&> (other.data);
numUsed = other.numUsed; numUsed = other.numUsed;
other.numUsed = 0; other.numUsed = 0;


+ 13
- 6
source/modules/juce_core/containers/juce_DynamicObject.cpp View File

@@ -30,6 +30,11 @@ DynamicObject::DynamicObject()
{ {
} }
DynamicObject::DynamicObject (const DynamicObject& other)
: properties (other.properties)
{
}
DynamicObject::~DynamicObject() DynamicObject::~DynamicObject()
{ {
} }
@@ -78,12 +83,9 @@ void DynamicObject::clear()
properties.clear(); properties.clear();
} }
DynamicObject::Ptr DynamicObject::clone()
void DynamicObject::cloneAllProperties()
{ {
DynamicObject* newCopy = new DynamicObject();
newCopy->properties = properties;
for (LinkedListPointer<NamedValueSet::NamedValue>* i = &(newCopy->properties.values);;)
for (LinkedListPointer<NamedValueSet::NamedValue>* i = &(properties.values);;)
{ {
if (NamedValueSet::NamedValue* const v = i->get()) if (NamedValueSet::NamedValue* const v = i->get())
{ {
@@ -93,8 +95,13 @@ DynamicObject::Ptr DynamicObject::clone()
else else
break; break;
} }
}
return newCopy;
DynamicObject::Ptr DynamicObject::clone()
{
Ptr d (new DynamicObject (*this));
d->cloneAllProperties();
return d;
} }
void DynamicObject::writeAsJSON (OutputStream& out, const int indentLevel, const bool allOnOneLine) void DynamicObject::writeAsJSON (OutputStream& out, const int indentLevel, const bool allOnOneLine)


+ 5
- 3
source/modules/juce_core/containers/juce_DynamicObject.h View File

@@ -46,9 +46,8 @@ class JUCE_API DynamicObject : public ReferenceCountedObject
public: public:
//============================================================================== //==============================================================================
DynamicObject(); DynamicObject();
/** Destructor. */
virtual ~DynamicObject();
DynamicObject (const DynamicObject&);
~DynamicObject();
typedef ReferenceCountedObjectPtr<DynamicObject> Ptr; typedef ReferenceCountedObjectPtr<DynamicObject> Ptr;
@@ -104,6 +103,9 @@ public:
/** Returns the NamedValueSet that holds the object's properties. */ /** Returns the NamedValueSet that holds the object's properties. */
NamedValueSet& getProperties() noexcept { return properties; } NamedValueSet& getProperties() noexcept { return properties; }
/** Calls var::clone() on all the properties that this object contains. */
void cloneAllProperties();
//============================================================================== //==============================================================================
/** Returns a clone of this object. /** Returns a clone of this object.
The default implementation of this method just returns a new DynamicObject The default implementation of this method just returns a new DynamicObject


+ 10
- 10
source/modules/juce_core/containers/juce_NamedValueSet.cpp View File

@@ -30,7 +30,7 @@ NamedValueSet::NamedValue::NamedValue() noexcept
{ {
} }
inline NamedValueSet::NamedValue::NamedValue (const Identifier n, const var& v)
inline NamedValueSet::NamedValue::NamedValue (Identifier n, const var& v)
: name (n), value (v) : name (n), value (v)
{ {
} }
@@ -49,22 +49,22 @@ NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (const NamedValu
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet::NamedValue::NamedValue (NamedValue&& other) noexcept NamedValueSet::NamedValue::NamedValue (NamedValue&& other) noexcept
: nextListItem (static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem)),
name (static_cast <Identifier&&> (other.name)),
value (static_cast <var&&> (other.value))
: nextListItem (static_cast<LinkedListPointer<NamedValue>&&> (other.nextListItem)),
name (static_cast<Identifier&&> (other.name)),
value (static_cast<var&&> (other.value))
{ {
} }
inline NamedValueSet::NamedValue::NamedValue (const Identifier n, var&& v)
: name (n), value (static_cast <var&&> (v))
inline NamedValueSet::NamedValue::NamedValue (Identifier n, var&& v)
: name (n), value (static_cast<var&&> (v))
{ {
} }
NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (NamedValue&& other) noexcept NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (NamedValue&& other) noexcept
{ {
nextListItem = static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem);
name = static_cast <Identifier&&> (other.name);
value = static_cast <var&&> (other.value);
nextListItem = static_cast<LinkedListPointer<NamedValue>&&> (other.nextListItem);
name = static_cast<Identifier&&> (other.name);
value = static_cast<var&&> (other.value);
return *this; return *this;
} }
#endif #endif
@@ -268,7 +268,7 @@ void NamedValueSet::setFromXmlAttributes (const XmlElement& xml)
for (int i = 0; i < numAtts; ++i) for (int i = 0; i < numAtts; ++i)
{ {
const String& name = xml.getAttributeName (i);
const String& name = xml.getAttributeName (i);
const String& value = xml.getAttributeValue (i); const String& value = xml.getAttributeValue (i);
if (name.startsWith ("base64:")) if (name.startsWith ("base64:"))


+ 9
- 9
source/modules/juce_core/containers/juce_NamedValueSet.h View File

@@ -43,21 +43,21 @@ public:
NamedValueSet() noexcept; NamedValueSet() noexcept;
/** Creates a copy of another set. */ /** Creates a copy of another set. */
NamedValueSet (const NamedValueSet& other);
NamedValueSet (const NamedValueSet&);
/** Replaces this set with a copy of another set. */ /** Replaces this set with a copy of another set. */
NamedValueSet& operator= (const NamedValueSet& other);
NamedValueSet& operator= (const NamedValueSet&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet (NamedValueSet&& other) noexcept;
NamedValueSet& operator= (NamedValueSet&& other) noexcept;
NamedValueSet (NamedValueSet&&) noexcept;
NamedValueSet& operator= (NamedValueSet&&) noexcept;
#endif #endif
/** Destructor. */ /** Destructor. */
~NamedValueSet(); ~NamedValueSet();
bool operator== (const NamedValueSet& other) const;
bool operator!= (const NamedValueSet& other) const;
bool operator== (const NamedValueSet&) const;
bool operator!= (const NamedValueSet&) const;
//============================================================================== //==============================================================================
/** Returns the total number of values that the set contains. */ /** Returns the total number of values that the set contains. */
@@ -135,14 +135,14 @@ private:
public: public:
NamedValue() noexcept; NamedValue() noexcept;
NamedValue (const NamedValue&); NamedValue (const NamedValue&);
NamedValue (const Identifier name, const var& value);
NamedValue (Identifier, const var&);
NamedValue& operator= (const NamedValue&); NamedValue& operator= (const NamedValue&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValue (NamedValue&&) noexcept; NamedValue (NamedValue&&) noexcept;
NamedValue (const Identifier name, var&& value);
NamedValue (Identifier, var&&);
NamedValue& operator= (NamedValue&&) noexcept; NamedValue& operator= (NamedValue&&) noexcept;
#endif #endif
bool operator== (const NamedValue& other) const noexcept;
bool operator== (const NamedValue&) const noexcept;
LinkedListPointer<NamedValue> nextListItem; LinkedListPointer<NamedValue> nextListItem;
Identifier name; Identifier name;


+ 43
- 50
source/modules/juce_core/containers/juce_OwnedArray.h View File

@@ -231,7 +231,7 @@ public:
@param objectToLookFor the object to look for @param objectToLookFor the object to look for
@returns the index at which the object was found, or -1 if it's not found @returns the index at which the object was found, or -1 if it's not found
*/ */
int indexOf (const ObjectClass* const objectToLookFor) const noexcept
int indexOf (const ObjectClass* objectToLookFor) const noexcept
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
ObjectClass* const* e = data.elements.getData(); ObjectClass* const* e = data.elements.getData();
@@ -249,7 +249,7 @@ public:
@param objectToLookFor the object to look for @param objectToLookFor the object to look for
@returns true if the object is in the array @returns true if the object is in the array
*/ */
bool contains (const ObjectClass* const objectToLookFor) const noexcept
bool contains (const ObjectClass* objectToLookFor) const noexcept
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
ObjectClass* const* e = data.elements.getData(); ObjectClass* const* e = data.elements.getData();
@@ -271,16 +271,17 @@ public:
Also be careful not to add the same object to the array more than once, Also be careful not to add the same object to the array more than once,
as this will obviously cause deletion of dangling pointers. as this will obviously cause deletion of dangling pointers.
@param newObject the new object to add to the array
@param newObject the new object to add to the array
@returns the new object that was added
@see set, insert, addIfNotAlreadyThere, addSorted @see set, insert, addIfNotAlreadyThere, addSorted
*/ */
ObjectClass* add (ObjectClass* const newObject) noexcept
ObjectClass* add (ObjectClass* newObject) noexcept
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
data.ensureAllocatedSize (numUsed + 1); data.ensureAllocatedSize (numUsed + 1);
jassert (data.elements != nullptr); jassert (data.elements != nullptr);
data.elements [numUsed++] = const_cast <ObjectClass*> (newObject);
return const_cast <ObjectClass*> (newObject);
data.elements [numUsed++] = newObject;
return newObject;
} }
/** Inserts a new object into the array at the given index. /** Inserts a new object into the array at the given index.
@@ -298,34 +299,31 @@ public:
@param indexToInsertAt the index at which the new element should be inserted @param indexToInsertAt the index at which the new element should be inserted
@param newObject the new object to add to the array @param newObject the new object to add to the array
@returns the new object that was added
@see add, addSorted, addIfNotAlreadyThere, set @see add, addSorted, addIfNotAlreadyThere, set
*/ */
void insert (int indexToInsertAt,
ObjectClass* const newObject) noexcept
ObjectClass* insert (int indexToInsertAt, ObjectClass* newObject) noexcept
{ {
if (indexToInsertAt >= 0)
{
const ScopedLockType lock (getLock());
if (indexToInsertAt < 0)
return add (newObject);
if (indexToInsertAt > numUsed)
indexToInsertAt = numUsed;
const ScopedLockType lock (getLock());
data.ensureAllocatedSize (numUsed + 1);
jassert (data.elements != nullptr);
if (indexToInsertAt > numUsed)
indexToInsertAt = numUsed;
ObjectClass** const e = data.elements + indexToInsertAt;
const int numToMove = numUsed - indexToInsertAt;
data.ensureAllocatedSize (numUsed + 1);
jassert (data.elements != nullptr);
if (numToMove > 0)
memmove (e + 1, e, sizeof (ObjectClass*) * (size_t) numToMove);
ObjectClass** const e = data.elements + indexToInsertAt;
const int numToMove = numUsed - indexToInsertAt;
*e = const_cast <ObjectClass*> (newObject);
++numUsed;
}
else
{
add (newObject);
}
if (numToMove > 0)
memmove (e + 1, e, sizeof (ObjectClass*) * (size_t) numToMove);
*e = newObject;
++numUsed;
return newObject;
} }
/** Inserts an array of values into this array at a given position. /** Inserts an array of values into this array at a given position.
@@ -374,13 +372,16 @@ public:
If the array already contains a matching object, nothing will be done. If the array already contains a matching object, nothing will be done.
@param newObject the new object to add to the array @param newObject the new object to add to the array
@returns the new object that was added
*/ */
void addIfNotAlreadyThere (ObjectClass* const newObject) noexcept
ObjectClass* addIfNotAlreadyThere (ObjectClass* newObject) noexcept
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
if (! contains (newObject)) if (! contains (newObject))
add (newObject); add (newObject);
return newObject;
} }
/** Replaces an object in the array with a different one. /** Replaces an object in the array with a different one.
@@ -396,9 +397,7 @@ public:
@param deleteOldElement whether to delete the object that's being replaced with the new one @param deleteOldElement whether to delete the object that's being replaced with the new one
@see add, insert, remove @see add, insert, remove
*/ */
void set (const int indexToChange,
const ObjectClass* const newObject,
const bool deleteOldElement = true)
ObjectClass* set (int indexToChange, ObjectClass* newObject, bool deleteOldElement = true)
{ {
if (indexToChange >= 0) if (indexToChange >= 0)
{ {
@@ -417,12 +416,12 @@ public:
toDelete.release(); toDelete.release();
} }
data.elements [indexToChange] = const_cast <ObjectClass*> (newObject);
data.elements [indexToChange] = newObject;
} }
else else
{ {
data.ensureAllocatedSize (numUsed + 1); data.ensureAllocatedSize (numUsed + 1);
data.elements [numUsed++] = const_cast <ObjectClass*> (newObject);
data.elements [numUsed++] = newObject;
} }
} }
} }
@@ -431,6 +430,8 @@ public:
jassertfalse; // you're trying to set an object at a negative index, which doesn't have jassertfalse; // you're trying to set an object at a negative index, which doesn't have
// any effect - but since the object is not being added, it may be leaking.. // any effect - but since the object is not being added, it may be leaking..
} }
return newObject;
} }
/** Adds elements from another array to the end of this array. /** Adds elements from another array to the end of this array.
@@ -504,10 +505,7 @@ public:
jassert (numElementsToAdd <= 0 || data.elements != nullptr); jassert (numElementsToAdd <= 0 || data.elements != nullptr);
while (--numElementsToAdd >= 0) while (--numElementsToAdd >= 0)
{
data.elements [numUsed] = new ObjectClass (*arrayToAddFrom.getUnchecked (startIndex++));
++numUsed;
}
data.elements [numUsed++] = createCopyIfNotNull (arrayToAddFrom.getUnchecked (startIndex++));
} }
/** Inserts a new object into the array assuming that the array is sorted. /** Inserts a new object into the array assuming that the array is sorted.
@@ -581,8 +579,7 @@ public:
@param deleteObject whether to delete the object that is removed @param deleteObject whether to delete the object that is removed
@see removeObject, removeRange @see removeObject, removeRange
*/ */
void remove (const int indexToRemove,
const bool deleteObject = true)
void remove (int indexToRemove, bool deleteObject = true)
{ {
ScopedPointer<ObjectClass> toDelete; ScopedPointer<ObjectClass> toDelete;
@@ -617,7 +614,7 @@ public:
@param indexToRemove the index of the element to remove @param indexToRemove the index of the element to remove
@see remove, removeObject, removeRange @see remove, removeObject, removeRange
*/ */
ObjectClass* removeAndReturn (const int indexToRemove)
ObjectClass* removeAndReturn (int indexToRemove)
{ {
ObjectClass* removedItem = nullptr; ObjectClass* removedItem = nullptr;
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
@@ -648,8 +645,7 @@ public:
@param deleteObject whether to delete the object (if it's found) @param deleteObject whether to delete the object (if it's found)
@see remove, removeRange @see remove, removeRange
*/ */
void removeObject (const ObjectClass* const objectToRemove,
const bool deleteObject = true)
void removeObject (const ObjectClass* objectToRemove, bool deleteObject = true)
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
ObjectClass** const e = data.elements.getData(); ObjectClass** const e = data.elements.getData();
@@ -677,9 +673,7 @@ public:
@param deleteObjects whether to delete the objects that get removed @param deleteObjects whether to delete the objects that get removed
@see remove, removeObject @see remove, removeObject
*/ */
void removeRange (int startIndex,
const int numberToRemove,
const bool deleteObjects = true)
void removeRange (int startIndex, int numberToRemove, bool deleteObjects = true)
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove); const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove);
@@ -719,7 +713,7 @@ public:
@see remove, removeObject, removeRange @see remove, removeObject, removeRange
*/ */
void removeLast (int howManyToRemove = 1, void removeLast (int howManyToRemove = 1,
const bool deleteObjects = true)
bool deleteObjects = true)
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
@@ -734,8 +728,8 @@ public:
If either of the indexes passed in is out-of-range, nothing will happen, If either of the indexes passed in is out-of-range, nothing will happen,
otherwise the two objects at these positions will be exchanged. otherwise the two objects at these positions will be exchanged.
*/ */
void swap (const int index1,
const int index2) noexcept
void swap (int index1,
int index2) noexcept
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
@@ -760,8 +754,7 @@ public:
@param newIndex the index at which you'd like this object to end up. If this @param newIndex the index at which you'd like this object to end up. If this
is less than zero, it will be moved to the end of the array is less than zero, it will be moved to the end of the array
*/ */
void move (const int currentIndex,
int newIndex) noexcept
void move (int currentIndex, int newIndex) noexcept
{ {
if (currentIndex != newIndex) if (currentIndex != newIndex)
{ {
@@ -859,7 +852,7 @@ public:
*/ */
template <class ElementComparator> template <class ElementComparator>
void sort (ElementComparator& comparator, void sort (ElementComparator& comparator,
const bool retainOrderOfEquivalentItems = false) const noexcept
bool retainOrderOfEquivalentItems = false) const noexcept
{ {
(void) comparator; // if you pass in an object with a static compareElements() method, this (void) comparator; // if you pass in an object with a static compareElements() method, this
// avoids getting warning messages about the parameter being unused // avoids getting warning messages about the parameter being unused


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

@@ -155,8 +155,8 @@ void PropertySet::removeValue (StringRef keyName)
void PropertySet::setValue (const String& keyName, const XmlElement* const xml) void PropertySet::setValue (const String& keyName, const XmlElement* const xml)
{ {
setValue (keyName, xml == nullptr ? var::null
: var (xml->createDocument (String::empty, true)));
setValue (keyName, xml == nullptr ? var()
: var (xml->createDocument ("", true)));
} }
bool PropertySet::containsKey (StringRef keyName) const noexcept bool PropertySet::containsKey (StringRef keyName) const noexcept


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

@@ -69,7 +69,7 @@ public:
@param keyName the name of the property to retrieve @param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist @param defaultReturnValue a value to return if the named property doesn't actually exist
*/ */
String getValue (StringRef keyName, const String& defaultReturnValue = String::empty) const noexcept;
String getValue (StringRef keyName, const String& defaultReturnValue = String()) const noexcept;
/** Returns one of the properties as an integer. /** Returns one of the properties as an integer.
@@ -109,8 +109,8 @@ public:
/** Returns one of the properties as an XML element. /** Returns one of the properties as an XML element.
The result will a new XMLElement object that the caller must delete. If may return 0 if the
key isn't found, or if the entry contains an string that isn't valid XML.
The result will a new XMLElement object that the caller must delete. If may return nullptr
if the key isn't found, or if the entry contains an string that isn't valid XML.
If the value isn't found in this set, then this will look for it in a fallback If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method), property set (if you've specified one with the setFallbackPropertySet() method),


+ 6
- 0
source/modules/juce_core/containers/juce_Variant.cpp View File

@@ -120,6 +120,9 @@ public:
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
{ {
if (otherType.isDouble() || otherType.isInt64() || otherType.isString())
return otherType.equals (otherData, data, *this);
return otherType.toInt (otherData) == data.intValue; return otherType.toInt (otherData) == data.intValue;
} }
@@ -147,6 +150,9 @@ public:
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
{ {
if (otherType.isDouble() || otherType.isString())
return otherType.equals (otherData, data, *this);
return otherType.toInt64 (otherData) == data.int64Value; return otherType.toInt64 (otherData) == data.int64Value;
} }


+ 5
- 5
source/modules/juce_core/files/juce_DirectoryIterator.h View File

@@ -32,16 +32,16 @@
//============================================================================== //==============================================================================
/** /**
Searches through a the files in a directory, returning each file that is found.
Searches through the files in a directory, returning each file that is found.
A DirectoryIterator will search through a directory and its subdirectories using A DirectoryIterator will search through a directory and its subdirectories using
a wildcard filepattern match. a wildcard filepattern match.
If you may be finding a large number of files, this is better than
using File::findChildFiles() because it doesn't block while it finds them
all, and this is more memory-efficient.
If you may be scanning a large number of files, it's usually smarter to use this
class than File::findChildFiles() because it allows you to stop at any time, rather
than having to wait for the entire scan to finish before getting the results.
It can also guess how far it's got using a wildly inaccurate algorithm.
It also provides an estimate of its progress, using a (highly inaccurate!) algorithm.
*/ */
class JUCE_API DirectoryIterator class JUCE_API DirectoryIterator
{ {


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

@@ -75,7 +75,7 @@ const File File::nonexistent;
String File::parseAbsolutePath (const String& p) String File::parseAbsolutePath (const String& p)
{ {
if (p.isEmpty()) if (p.isEmpty())
return String::empty;
return String();
#if JUCE_WINDOWS #if JUCE_WINDOWS
// Windows.. // Windows..
@@ -322,7 +322,7 @@ String File::getFileNameWithoutExtension() const
bool File::isAChildOf (const File& potentialParent) const bool File::isAChildOf (const File& potentialParent) const
{ {
if (potentialParent == File::nonexistent)
if (potentialParent.fullPath.isEmpty())
return false; return false;
const String ourPath (getPathUpToLastSlash()); const String ourPath (getPathUpToLastSlash());
@@ -482,11 +482,11 @@ bool File::loadFileAsData (MemoryBlock& destBlock) const
String File::loadFileAsString() const String File::loadFileAsString() const
{ {
if (! existsAsFile()) if (! existsAsFile())
return String::empty;
return String();
FileInputStream in (*this); FileInputStream in (*this);
return in.openedOk() ? in.readEntireStreamAsString() return in.openedOk() ? in.readEntireStreamAsString()
: String::empty;
: String();
} }
void File::readLines (StringArray& destLines) const void File::readLines (StringArray& destLines) const
@@ -598,7 +598,7 @@ String File::getFileExtension() const
if (indexOfDot > fullPath.lastIndexOfChar (separator)) if (indexOfDot > fullPath.lastIndexOfChar (separator))
return fullPath.substring (indexOfDot); return fullPath.substring (indexOfDot);
return String::empty;
return String();
} }
bool File::hasFileExtension (StringRef possibleSuffix) const bool File::hasFileExtension (StringRef possibleSuffix) const
@@ -629,7 +629,7 @@ bool File::hasFileExtension (StringRef possibleSuffix) const
File File::withFileExtension (StringRef newExtension) const File File::withFileExtension (StringRef newExtension) const
{ {
if (fullPath.isEmpty()) if (fullPath.isEmpty())
return File::nonexistent;
return File();
String filePart (getFileName()); String filePart (getFileName());


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

@@ -741,7 +741,7 @@ public:
@see revealToUser @see revealToUser
*/ */
bool startAsProcess (const String& parameters = String::empty) const;
bool startAsProcess (const String& parameters = String()) const;
/** Opens Finder, Explorer, or whatever the OS uses, to show the user this file's location. /** Opens Finder, Explorer, or whatever the OS uses, to show the user this file's location.
@see startAsProcess @see startAsProcess


+ 41
- 0
source/modules/juce_core/files/juce_FileFilter.cpp View File

@@ -0,0 +1,41 @@
/*
==============================================================================
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
==============================================================================
*/
FileFilter::FileFilter (const String& filterDescription)
: description (filterDescription)
{
}
FileFilter::~FileFilter()
{
}
const String& FileFilter::getDescription() const noexcept
{
return description;
}

+ 77
- 0
source/modules/juce_core/files/juce_FileFilter.h View File

@@ -0,0 +1,77 @@
/*
==============================================================================
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_FILEFILTER_H_INCLUDED
#define JUCE_FILEFILTER_H_INCLUDED
//==============================================================================
/**
Interface for deciding which files are suitable for something.
For example, this is used by DirectoryContentsList to select which files
go into the list.
@see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
*/
class JUCE_API FileFilter
{
public:
//==============================================================================
/** Creates a filter with the given description.
The description can be returned later with the getDescription() method.
*/
FileFilter (const String& filterDescription);
/** Destructor. */
virtual ~FileFilter();
//==============================================================================
/** Returns the description that the filter was created with. */
const String& getDescription() const noexcept;
//==============================================================================
/** Should return true if this file is suitable for inclusion in whatever context
the object is being used.
*/
virtual bool isFileSuitable (const File& file) const = 0;
/** Should return true if this directory is suitable for inclusion in whatever context
the object is being used.
*/
virtual bool isDirectorySuitable (const File& file) const = 0;
protected:
//==============================================================================
String description;
};
#endif // JUCE_FILEFILTER_H_INCLUDED

+ 1
- 1
source/modules/juce_core/files/juce_FileSearchPath.h View File

@@ -101,7 +101,7 @@ public:
/** Merges another search path into this one. /** Merges another search path into this one.
This will remove any duplicate directories. This will remove any duplicate directories.
*/ */
void addPath (const FileSearchPath& other);
void addPath (const FileSearchPath&);
/** Removes any directories that are actually subdirectories of one of the other directories in the search path. /** Removes any directories that are actually subdirectories of one of the other directories in the search path.


+ 2
- 2
source/modules/juce_core/files/juce_TemporaryFile.cpp View File

@@ -50,7 +50,7 @@ TemporaryFile::TemporaryFile (const File& target, const int optionFlags)
targetFile (target) targetFile (target)
{ {
// If you use this constructor, you need to give it a valid target file! // If you use this constructor, you need to give it a valid target file!
jassert (targetFile != File::nonexistent);
jassert (targetFile != File());
} }
TemporaryFile::TemporaryFile (const File& target, const File& temporary) TemporaryFile::TemporaryFile (const File& target, const File& temporary)
@@ -79,7 +79,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const
{ {
// This method only works if you created this object with the constructor // This method only works if you created this object with the constructor
// that takes a target file! // that takes a target file!
jassert (targetFile != File::nonexistent);
jassert (targetFile != File());
if (temporaryFile.exists()) if (temporaryFile.exists())
{ {


+ 1
- 1
source/modules/juce_core/files/juce_TemporaryFile.h View File

@@ -89,7 +89,7 @@ public:
The file will not be created until you write to it. And remember that when The file will not be created until you write to it. And remember that when
this object is deleted, the file will also be deleted! this object is deleted, the file will also be deleted!
*/ */
TemporaryFile (const String& suffix = String::empty,
TemporaryFile (const String& suffix = String(),
int optionFlags = 0); int optionFlags = 0);
/** Creates a temporary file in the same directory as a specified file. /** Creates a temporary file in the same directory as a specified file.


+ 77
- 0
source/modules/juce_core/files/juce_WildcardFileFilter.cpp View File

@@ -0,0 +1,77 @@
/*
==============================================================================
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
==============================================================================
*/
WildcardFileFilter::WildcardFileFilter (const String& fileWildcardPatterns,
const String& directoryWildcardPatterns,
const String& desc)
: FileFilter (desc.isEmpty() ? fileWildcardPatterns
: (desc + " (" + fileWildcardPatterns + ")"))
{
parse (fileWildcardPatterns, fileWildcards);
parse (directoryWildcardPatterns, directoryWildcards);
}
WildcardFileFilter::~WildcardFileFilter()
{
}
bool WildcardFileFilter::isFileSuitable (const File& file) const
{
return match (file, fileWildcards);
}
bool WildcardFileFilter::isDirectorySuitable (const File& file) const
{
return match (file, directoryWildcards);
}
//==============================================================================
void WildcardFileFilter::parse (const String& pattern, StringArray& result)
{
result.addTokens (pattern.toLowerCase(), ";,", "\"'");
result.trim();
result.removeEmptyStrings();
// special case for *.*, because people use it to mean "any file", but it
// would actually ignore files with no extension.
for (int i = result.size(); --i >= 0;)
if (result[i] == "*.*")
result.set (i, "*");
}
bool WildcardFileFilter::match (const File& file, const StringArray& wildcards)
{
const String filename (file.getFileName());
for (int i = wildcards.size(); --i >= 0;)
if (filename.matchesWildcard (wildcards[i], true))
return true;
return false;
}

+ 86
- 0
source/modules/juce_core/files/juce_WildcardFileFilter.h View File

@@ -0,0 +1,86 @@
/*
==============================================================================
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_WILDCARDFILEFILTER_H_INCLUDED
#define JUCE_WILDCARDFILEFILTER_H_INCLUDED
//==============================================================================
/**
A type of FileFilter that works by wildcard pattern matching.
This filter only allows files that match one of the specified patterns, but
allows all directories through.
@see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
*/
class JUCE_API WildcardFileFilter : public FileFilter
{
public:
//==============================================================================
/**
Creates a wildcard filter for one or more patterns.
The wildcardPatterns parameter is a comma or semicolon-delimited set of
patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav
or .aiff.
Passing an empty string as a pattern will fail to match anything, so by leaving
either the file or directory pattern parameter empty means you can control
whether files or directories are found.
The description is a name to show the user in a list of possible patterns, so
for the wav/aiff example, your description might be "audio files".
*/
WildcardFileFilter (const String& fileWildcardPatterns,
const String& directoryWildcardPatterns,
const String& description);
/** Destructor. */
~WildcardFileFilter();
//==============================================================================
/** Returns true if the filename matches one of the patterns specified. */
bool isFileSuitable (const File& file) const;
/** This always returns true. */
bool isDirectorySuitable (const File& file) const;
private:
//==============================================================================
StringArray fileWildcards, directoryWildcards;
static void parse (const String& pattern, StringArray& result);
static bool match (const File& file, const StringArray& wildcards);
JUCE_LEAK_DETECTOR (WildcardFileFilter)
};
#endif // JUCE_WILDCARDFILEFILTER_H_INCLUDED

+ 19
- 54
source/modules/juce_core/javascript/juce_JSON.cpp View File

@@ -35,7 +35,7 @@ public:
switch (t.getAndAdvance()) switch (t.getAndAdvance())
{ {
case 0: result = var::null; return Result::ok();
case 0: result = var(); return Result::ok();
case '{': return parseObject (t, result); case '{': return parseObject (t, result);
case '[': return parseArray (t, result); case '[': return parseArray (t, result);
} }
@@ -100,7 +100,6 @@ public:
return Result::ok(); return Result::ok();
} }
private:
static Result parseAny (String::CharPointerType& t, var& result) static Result parseAny (String::CharPointerType& t, var& result)
{ {
t = t.findEndOfWhitespace(); t = t.findEndOfWhitespace();
@@ -148,7 +147,7 @@ private:
if (t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'l' && t2.getAndAdvance() == 'l') if (t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'l' && t2.getAndAdvance() == 'l')
{ {
t = t2; t = t2;
result = var::null;
result = var();
return Result::ok(); return Result::ok();
} }
break; break;
@@ -160,6 +159,7 @@ private:
return createFail ("Syntax error", &t); return createFail ("Syntax error", &t);
} }
private:
static Result createFail (const char* const message, const String::CharPointerType* location = nullptr) static Result createFail (const char* const message, const String::CharPointerType* location = nullptr)
{ {
String m (message); String m (message);
@@ -254,7 +254,7 @@ private:
if (c2 != ':') if (c2 != ':')
return createFail ("Expected ':', but found", &oldT); return createFail ("Expected ':', but found", &oldT);
resultProperties.set (propertyName, var::null);
resultProperties.set (propertyName, var());
var* propertyValue = resultProperties.getVarPointer (propertyName); var* propertyValue = resultProperties.getVarPointer (propertyName);
Result r2 (parseAny (t, *propertyValue)); Result r2 (parseAny (t, *propertyValue));
@@ -300,7 +300,7 @@ private:
return createFail ("Unexpected end-of-input in array declaration"); return createFail ("Unexpected end-of-input in array declaration");
t = oldT; t = oldT;
destArray->add (var::null);
destArray->add (var());
Result r (parseAny (t, destArray->getReference (destArray->size() - 1))); Result r (parseAny (t, destArray->getReference (destArray->size() - 1)));
if (r.failed()) if (r.failed())
@@ -460,51 +460,6 @@ public:
out << ']'; out << ']';
} }
/* static void writeObject (OutputStream& out, DynamicObject& object,
const int indentLevel, const bool allOnOneLine)
{
NamedValueSet& props = object.getProperties();
out << '{';
if (! allOnOneLine)
out << newLine;
LinkedListPointer<NamedValueSet::NamedValue>* i = &(props.values);
for (;;)
{
NamedValueSet::NamedValue* const v = i->get();
if (v == nullptr)
break;
if (! allOnOneLine)
writeSpaces (out, indentLevel + indentSize);
out << '"';
writeString (out, v->name);
out << "\": ";
write (out, v->value, indentLevel + indentSize, allOnOneLine);
if (v->nextListItem.get() != nullptr)
{
if (allOnOneLine)
out << ", ";
else
out << ',' << newLine;
}
else if (! allOnOneLine)
out << newLine;
i = &(v->nextListItem);
}
if (! allOnOneLine)
writeSpaces (out, indentLevel);
out << '}';
}*/
enum { indentSize = 2 }; enum { indentSize = 2 };
}; };
@@ -513,8 +468,18 @@ var JSON::parse (const String& text)
{ {
var result; var result;
if (! JSONParser::parseObjectOrArray (text.getCharPointer(), result))
result = var::null;
if (! parse (text, result))
result = var();
return result;
}
var JSON::fromString (StringRef text)
{
var result;
if (! JSONParser::parseAny (text.text, result))
result = var();
return result; return result;
} }
@@ -610,7 +575,7 @@ public:
{ {
switch (r.nextInt (depth > 3 ? 6 : 8)) switch (r.nextInt (depth > 3 ? 6 : 8))
{ {
case 0: return var::null;
case 0: return var();
case 1: return r.nextInt(); case 1: return r.nextInt();
case 2: return r.nextInt64(); case 2: return r.nextInt64();
case 3: return r.nextBool(); case 3: return r.nextBool();
@@ -638,7 +603,7 @@ public:
} }
default: default:
return var::null;
return var();
} }
} }


+ 16
- 1
source/modules/juce_core/javascript/juce_JSON.h View File

@@ -53,6 +53,10 @@ public:
If you're not interested in the error message, you can use one of the other If you're not interested in the error message, you can use one of the other
shortcut parse methods, which simply return a var::null if the parsing fails. shortcut parse methods, which simply return a var::null if the parsing fails.
Note that this will only parse valid JSON, which means that the item given must
be either an object or an array definition. If you want to also be able to parse
any kind of primitive JSON object, use the fromString() method.
*/ */
static Result parse (const String& text, var& parsedResult); static Result parse (const String& text, var& parsedResult);
@@ -60,6 +64,10 @@ public:
If the parsing fails, this simply returns var::null - if you need to find out more If the parsing fails, this simply returns var::null - if you need to find out more
detail about the parse error, use the alternative parse() method which returns a Result. detail about the parse error, use the alternative parse() method which returns a Result.
Note that this will only parse valid JSON, which means that the item given must
be either an object or an array definition. If you want to also be able to parse
any kind of primitive JSON object, use the fromString() method.
*/ */
static var parse (const String& text); static var parse (const String& text);
@@ -94,6 +102,13 @@ public:
static String toString (const var& objectToFormat, static String toString (const var& objectToFormat,
bool allOnOneLine = false); bool allOnOneLine = false);
/** Parses a string that was created with the toString() method.
This is slightly different to the parse() methods because they will reject primitive
values and only accept array or object definitions, whereas this method will handle
either.
*/
static var fromString (StringRef);
/** Writes a JSON-formatted representation of the var object to the given stream. /** Writes a JSON-formatted representation of the var object to the given stream.
If allOnOneLine is true, the result will be compacted into a single line of text If allOnOneLine is true, the result will be compacted into a single line of text
with no carriage-returns. If false, it will be laid-out in a more human-readable format. with no carriage-returns. If false, it will be laid-out in a more human-readable format.
@@ -106,7 +121,7 @@ public:
/** Returns a version of a string with any extended characters escaped. */ /** Returns a version of a string with any extended characters escaped. */
static String escapeString (StringRef); static String escapeString (StringRef);
/** Parses a quoted string in JSON format, returning the un-escaped result in the
/** Parses a quoted string-literal in JSON format, returning the un-escaped result in the
result parameter, and an error message in case the content was illegal. result parameter, and an error message in case the content was illegal.
This advances the text parameter, leaving it positioned after the closing quote. This advances the text parameter, leaving it positioned after the closing quote.
*/ */


+ 37
- 20
source/modules/juce_core/javascript/juce_Javascript.cpp View File

@@ -90,15 +90,6 @@ struct JavascriptEngine::RootObject : public DynamicObject
return ExpPtr (tb.parseExpression())->getResult (Scope (nullptr, this, this)); return ExpPtr (tb.parseExpression())->getResult (Scope (nullptr, this, this));
} }
var invoke (Identifier function, const var::NativeFunctionArgs& args)
{
if (const var* m = getProperties().getVarPointer (function))
if (FunctionObject* fo = dynamic_cast<FunctionObject*> (m->getObject()))
return fo->invoke (Scope (nullptr, this, this), args);
return var::undefined();
}
//============================================================================== //==============================================================================
static bool areTypeEqual (const var& a, const var& b) static bool areTypeEqual (const var& a, const var& b)
{ {
@@ -191,6 +182,32 @@ struct JavascriptEngine::RootObject : public DynamicObject
: var::undefined(); : var::undefined();
} }
bool findAndInvokeMethod (Identifier function, const var::NativeFunctionArgs& args, var& result) const
{
const NamedValueSet& props = scope->getProperties();
DynamicObject* target = args.thisObject.getDynamicObject();
if (target == nullptr || target == scope)
{
if (const var* m = props.getVarPointer (function))
{
if (FunctionObject* fo = dynamic_cast<FunctionObject*> (m->getObject()))
{
result = fo->invoke (*this, args);
return true;
}
}
}
for (int i = 0; i < props.size(); ++i)
if (DynamicObject* o = props.getValueAt (i).getDynamicObject())
if (Scope (this, root, o).findAndInvokeMethod (function, args, result))
return true;
return false;
}
void checkTimeOut (const CodeLocation& location) const void checkTimeOut (const CodeLocation& location) const
{ {
if (Time::getCurrentTime() > root->timeout) if (Time::getCurrentTime() > root->timeout)
@@ -281,11 +298,10 @@ struct JavascriptEngine::RootObject : public DynamicObject
if (r == returnWasHit) return r; if (r == returnWasHit) return r;
if (r == breakWasHit) break; if (r == breakWasHit) break;
if (r == continueWasHit) continue;
iterator->perform (s, nullptr); iterator->perform (s, nullptr);
if (isDoLoop && ! condition->getResult (s))
if (isDoLoop && r != continueWasHit && ! condition->getResult (s))
break; break;
} }
@@ -656,14 +672,13 @@ struct JavascriptEngine::RootObject : public DynamicObject
var getResult (const Scope& s) const override var getResult (const Scope& s) const override
{ {
var function (object->getResult (s));
if (DotOperator* dot = dynamic_cast<DotOperator*> (object.get())) if (DotOperator* dot = dynamic_cast<DotOperator*> (object.get()))
{ {
var thisObject (dot->parent->getResult (s)); var thisObject (dot->parent->getResult (s));
return invokeFunction (s, s.findFunctionCall (location, thisObject, dot->child), thisObject); return invokeFunction (s, s.findFunctionCall (location, thisObject, dot->child), thisObject);
} }
var function (object->getResult (s));
return invokeFunction (s, function, var (s.scope)); return invokeFunction (s, function, var (s.scope));
} }
@@ -763,7 +778,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
void writeAsJSON (OutputStream& out, int /*indentLevel*/, bool /*allOnOneLine*/) override void writeAsJSON (OutputStream& out, int /*indentLevel*/, bool /*allOnOneLine*/) override
{ {
out << "function" << functionCode;
out << "function " << functionCode;
} }
var invoke (const Scope& s, const var::NativeFunctionArgs& args) const var invoke (const Scope& s, const var::NativeFunctionArgs& args) const
@@ -773,9 +788,9 @@ struct JavascriptEngine::RootObject : public DynamicObject
static const Identifier thisIdent ("this"); static const Identifier thisIdent ("this");
functionRoot->setProperty (thisIdent, args.thisObject); functionRoot->setProperty (thisIdent, args.thisObject);
const int numArgs = jmin (parameters.size(), args.numArguments);
for (int i = 0; i < numArgs; ++i)
functionRoot->setProperty (parameters.getReference(i), args.arguments[i]);
for (int i = 0; i < parameters.size(); ++i)
functionRoot->setProperty (parameters.getReference(i),
i < args.numArguments ? args.arguments[i] : var::undefined());
var result; var result;
body->perform (Scope (&s, s.root, functionRoot), &result); body->perform (Scope (&s, s.root, functionRoot), &result);
@@ -1228,7 +1243,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
if (matchIf (TokenTypes::openParen)) return parseSuffixes (matchCloseParen (parseExpression())); if (matchIf (TokenTypes::openParen)) return parseSuffixes (matchCloseParen (parseExpression()));
if (matchIf (TokenTypes::true_)) return parseSuffixes (new LiteralValue (location, (int) 1)); if (matchIf (TokenTypes::true_)) return parseSuffixes (new LiteralValue (location, (int) 1));
if (matchIf (TokenTypes::false_)) return parseSuffixes (new LiteralValue (location, (int) 0)); if (matchIf (TokenTypes::false_)) return parseSuffixes (new LiteralValue (location, (int) 0));
if (matchIf (TokenTypes::null_)) return parseSuffixes (new LiteralValue (location, var::null));
if (matchIf (TokenTypes::null_)) return parseSuffixes (new LiteralValue (location, var()));
if (matchIf (TokenTypes::undefined)) return parseSuffixes (new Expression (location)); if (matchIf (TokenTypes::undefined)) return parseSuffixes (new Expression (location));
if (currentType == TokenTypes::literal) if (currentType == TokenTypes::literal)
@@ -1674,18 +1689,20 @@ var JavascriptEngine::evaluate (const String& code, Result* result)
var JavascriptEngine::callFunction (Identifier function, const var::NativeFunctionArgs& args, Result* result) var JavascriptEngine::callFunction (Identifier function, const var::NativeFunctionArgs& args, Result* result)
{ {
var returnVal (var::undefined());
try try
{ {
prepareTimeout(); prepareTimeout();
if (result != nullptr) *result = Result::ok(); if (result != nullptr) *result = Result::ok();
return root->invoke (function, args);
RootObject::Scope (nullptr, root, root).findAndInvokeMethod (function, args, returnVal);
} }
catch (String& error) catch (String& error)
{ {
if (result != nullptr) *result = Result::fail (error); if (result != nullptr) *result = Result::fail (error);
} }
return var::undefined();
return returnVal;
} }
#if JUCE_MSVC #if JUCE_MSVC


+ 1
- 2
source/modules/juce_core/javascript/juce_Javascript.h View File

@@ -26,7 +26,6 @@
============================================================================== ==============================================================================
*/ */
/** /**
A simple javascript interpreter! A simple javascript interpreter!
@@ -98,7 +97,7 @@ public:
RelativeTime maximumExecutionTime; RelativeTime maximumExecutionTime;
private: private:
struct RootObject;
JUCE_PUBLIC_IN_DLL_BUILD (struct RootObject)
ReferenceCountedObjectPtr<RootObject> root; ReferenceCountedObjectPtr<RootObject> root;
void prepareTimeout() const; void prepareTimeout() const;


+ 2
- 0
source/modules/juce_core/juce_core.cpp View File

@@ -165,6 +165,8 @@ namespace juce
#include "zip/juce_GZIPDecompressorInputStream.cpp" #include "zip/juce_GZIPDecompressorInputStream.cpp"
#include "zip/juce_GZIPCompressorOutputStream.cpp" #include "zip/juce_GZIPCompressorOutputStream.cpp"
#include "zip/juce_ZipFile.cpp" #include "zip/juce_ZipFile.cpp"
#include "files/juce_FileFilter.cpp"
#include "files/juce_WildcardFileFilter.cpp"
//============================================================================== //==============================================================================
#if JUCE_MAC || JUCE_IOS #if JUCE_MAC || JUCE_IOS


+ 2
- 0
source/modules/juce_core/juce_core.h View File

@@ -232,6 +232,8 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe
#include "files/juce_FileSearchPath.h" #include "files/juce_FileSearchPath.h"
#include "files/juce_MemoryMappedFile.h" #include "files/juce_MemoryMappedFile.h"
#include "files/juce_TemporaryFile.h" #include "files/juce_TemporaryFile.h"
#include "files/juce_FileFilter.h"
#include "files/juce_WildcardFileFilter.h"
#include "streams/juce_FileInputSource.h" #include "streams/juce_FileInputSource.h"
#include "logging/juce_FileLogger.h" #include "logging/juce_FileLogger.h"
#include "javascript/juce_JSON.h" #include "javascript/juce_JSON.h"


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

@@ -951,7 +951,7 @@ String BigInteger::toString (const int base, const int minimumNumCharacters) con
else else
{ {
jassertfalse; // can't do the specified base! jassertfalse; // can't do the specified base!
return String::empty;
return String();
} }
s = s.paddedLeft ('0', minimumNumCharacters); s = s.paddedLeft ('0', minimumNumCharacters);


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

@@ -65,11 +65,11 @@ public:
BigInteger (int64 value); BigInteger (int64 value);
/** Creates a copy of another BigInteger. */ /** Creates a copy of another BigInteger. */
BigInteger (const BigInteger& other);
BigInteger (const BigInteger&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
BigInteger (BigInteger&& other) noexcept;
BigInteger& operator= (BigInteger&& other) noexcept;
BigInteger (BigInteger&&) noexcept;
BigInteger& operator= (BigInteger&&) noexcept;
#endif #endif
/** Destructor. */ /** Destructor. */
@@ -77,10 +77,10 @@ public:
//============================================================================== //==============================================================================
/** Copies another BigInteger onto this one. */ /** Copies another BigInteger onto this one. */
BigInteger& operator= (const BigInteger& other);
BigInteger& operator= (const BigInteger&);
/** Swaps the internal contents of this with another object. */ /** Swaps the internal contents of this with another object. */
void swapWith (BigInteger& other) noexcept;
void swapWith (BigInteger&) noexcept;
//============================================================================== //==============================================================================
/** Returns the value of a specified bit in the number. /** Returns the value of a specified bit in the number.
@@ -183,14 +183,14 @@ public:
//============================================================================== //==============================================================================
// All the standard arithmetic ops... // All the standard arithmetic ops...
BigInteger& operator+= (const BigInteger& other);
BigInteger& operator-= (const BigInteger& other);
BigInteger& operator*= (const BigInteger& other);
BigInteger& operator/= (const BigInteger& other);
BigInteger& operator|= (const BigInteger& other);
BigInteger& operator&= (const BigInteger& other);
BigInteger& operator^= (const BigInteger& other);
BigInteger& operator%= (const BigInteger& other);
BigInteger& operator+= (const BigInteger&);
BigInteger& operator-= (const BigInteger&);
BigInteger& operator*= (const BigInteger&);
BigInteger& operator/= (const BigInteger&);
BigInteger& operator|= (const BigInteger&);
BigInteger& operator&= (const BigInteger&);
BigInteger& operator^= (const BigInteger&);
BigInteger& operator%= (const BigInteger&);
BigInteger& operator<<= (int numBitsToShift); BigInteger& operator<<= (int numBitsToShift);
BigInteger& operator>>= (int numBitsToShift); BigInteger& operator>>= (int numBitsToShift);
BigInteger& operator++(); BigInteger& operator++();
@@ -199,23 +199,23 @@ public:
BigInteger operator-- (int); BigInteger operator-- (int);
BigInteger operator-() const; BigInteger operator-() const;
BigInteger operator+ (const BigInteger& other) const;
BigInteger operator- (const BigInteger& other) const;
BigInteger operator* (const BigInteger& other) const;
BigInteger operator/ (const BigInteger& other) const;
BigInteger operator| (const BigInteger& other) const;
BigInteger operator& (const BigInteger& other) const;
BigInteger operator^ (const BigInteger& other) const;
BigInteger operator% (const BigInteger& other) const;
BigInteger operator+ (const BigInteger&) const;
BigInteger operator- (const BigInteger&) const;
BigInteger operator* (const BigInteger&) const;
BigInteger operator/ (const BigInteger&) const;
BigInteger operator| (const BigInteger&) const;
BigInteger operator& (const BigInteger&) const;
BigInteger operator^ (const BigInteger&) const;
BigInteger operator% (const BigInteger&) const;
BigInteger operator<< (int numBitsToShift) const; BigInteger operator<< (int numBitsToShift) const;
BigInteger operator>> (int numBitsToShift) const; BigInteger operator>> (int numBitsToShift) const;
bool operator== (const BigInteger& other) const noexcept;
bool operator!= (const BigInteger& other) const noexcept;
bool operator< (const BigInteger& other) const noexcept;
bool operator<= (const BigInteger& other) const noexcept;
bool operator> (const BigInteger& other) const noexcept;
bool operator>= (const BigInteger& other) const noexcept;
bool operator== (const BigInteger&) const noexcept;
bool operator!= (const BigInteger&) const noexcept;
bool operator< (const BigInteger&) const noexcept;
bool operator<= (const BigInteger&) const noexcept;
bool operator> (const BigInteger&) const noexcept;
bool operator>= (const BigInteger&) const noexcept;
//============================================================================== //==============================================================================
/** Does a signed comparison of two BigIntegers. /** Does a signed comparison of two BigIntegers.
@@ -243,8 +243,7 @@ public:
*/ */
void divideBy (const BigInteger& divisor, BigInteger& remainder); void divideBy (const BigInteger& divisor, BigInteger& remainder);
/** Returns the largest value that will divide both this value and the one passed-in.
*/
/** Returns the largest value that will divide both this value and the one passed-in. */
BigInteger findGreatestCommonDivisor (BigInteger other) const; BigInteger findGreatestCommonDivisor (BigInteger other) const;
/** Performs a combined exponent and modulo operation. /** Performs a combined exponent and modulo operation.
@@ -310,12 +309,12 @@ public:
private: private:
//============================================================================== //==============================================================================
HeapBlock <uint32> values;
HeapBlock<uint32> values;
size_t numValues; size_t numValues;
int highestBit; int highestBit;
bool negative; bool negative;
void ensureSize (size_t numVals);
void ensureSize (size_t);
void shiftLeft (int bits, int startBit); void shiftLeft (int bits, int startBit);
void shiftRight (int bits, int startBit); void shiftRight (int bits, int startBit);


+ 5
- 7
source/modules/juce_core/maths/juce_Expression.cpp View File

@@ -53,7 +53,7 @@ public:
virtual String getName() const virtual String getName() const
{ {
jassertfalse; // You shouldn't call this for an expression that's not actually a function! jassertfalse; // You shouldn't call this for an expression that's not actually a function!
return String::empty;
return String();
} }
virtual void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) virtual void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth)
@@ -188,12 +188,10 @@ struct Expression::Helpers
if (input != left && input != right) if (input != left && input != right)
return TermPtr(); return TermPtr();
const Term* const dest = findDestinationFor (topLevelTerm, this);
if (dest == nullptr)
return new Constant (overallTarget, false);
if (const Term* const dest = findDestinationFor (topLevelTerm, this))
return dest->createTermToEvaluateInput (scope, this, overallTarget, topLevelTerm);
return dest->createTermToEvaluateInput (scope, this, overallTarget, topLevelTerm);
return new Constant (overallTarget, false);
} }
}; };
@@ -1181,5 +1179,5 @@ void Expression::Scope::visitRelativeScope (const String& scopeName, Visitor&) c
String Expression::Scope::getScopeUID() const String Expression::Scope::getScopeUID() const
{ {
return String::empty;
return String();
} }

+ 9
- 9
source/modules/juce_core/maths/juce_Expression.h View File

@@ -59,14 +59,14 @@ public:
explicit Expression (double constant); explicit Expression (double constant);
/** Creates a copy of an expression. */ /** Creates a copy of an expression. */
Expression (const Expression& other);
Expression (const Expression&);
/** Copies another expression. */ /** Copies another expression. */
Expression& operator= (const Expression& other);
Expression& operator= (const Expression&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Expression (Expression&& other) noexcept;
Expression& operator= (Expression&& other) noexcept;
Expression (Expression&&) noexcept;
Expression& operator= (Expression&&) noexcept;
#endif #endif
/** Creates an expression by parsing a string. /** Creates an expression by parsing a string.
@@ -78,14 +78,14 @@ public:
/** Returns a string version of the expression. */ /** Returns a string version of the expression. */
String toString() const; String toString() const;
/** Returns an expression which is an addtion operation of two existing expressions. */
Expression operator+ (const Expression& other) const;
/** Returns an expression which is an addition operation of two existing expressions. */
Expression operator+ (const Expression&) const;
/** Returns an expression which is a subtraction operation of two existing expressions. */ /** Returns an expression which is a subtraction operation of two existing expressions. */
Expression operator- (const Expression& other) const;
Expression operator- (const Expression&) const;
/** Returns an expression which is a multiplication operation of two existing expressions. */ /** Returns an expression which is a multiplication operation of two existing expressions. */
Expression operator* (const Expression& other) const;
Expression operator* (const Expression&) const;
/** Returns an expression which is a division operation of two existing expressions. */ /** Returns an expression which is a division operation of two existing expressions. */
Expression operator/ (const Expression& other) const;
Expression operator/ (const Expression&) const;
/** Returns an expression which performs a negation operation on an existing expression. */ /** Returns an expression which performs a negation operation on an existing expression. */
Expression operator-() const; Expression operator-() const;


+ 17
- 14
source/modules/juce_core/memory/juce_Atomic.h View File

@@ -187,8 +187,8 @@ private:
/* /*
The following code is in the header so that the atomics can be inlined where possible... The following code is in the header so that the atomics can be inlined where possible...
*/ */
#if JUCE_IOS || (JUCE_MAC && (JUCE_PPC || JUCE_CLANG || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)))
#define JUCE_ATOMICS_MAC 1 // Older OSX builds using gcc4.1 or earlier
#if JUCE_MAC && (JUCE_PPC || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
#define JUCE_ATOMICS_MAC_LEGACY 1 // Older OSX builds using gcc4.1 or earlier
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
#define JUCE_MAC_ATOMICS_VOLATILE #define JUCE_MAC_ATOMICS_VOLATILE
@@ -196,7 +196,7 @@ private:
#define JUCE_MAC_ATOMICS_VOLATILE volatile #define JUCE_MAC_ATOMICS_VOLATILE volatile
#endif #endif
#if JUCE_PPC || JUCE_IOS
#if JUCE_PPC
// None of these atomics are available for PPC or for iOS 3.1 or earlier!! // None of these atomics are available for PPC or for iOS 3.1 or earlier!!
template <typename Type> static Type OSAtomicAdd64Barrier (Type b, JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return *a += b; } template <typename Type> static Type OSAtomicAdd64Barrier (Type b, JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return *a += b; }
template <typename Type> static Type OSAtomicIncrement64Barrier (JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return ++*a; } template <typename Type> static Type OSAtomicIncrement64Barrier (JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return ++*a; }
@@ -207,7 +207,7 @@ private:
#endif #endif
//============================================================================== //==============================================================================
#elif JUCE_GCC
#elif JUCE_GCC || JUCE_CLANG
#define JUCE_ATOMICS_GCC 1 // GCC with intrinsics #define JUCE_ATOMICS_GCC 1 // GCC with intrinsics
#if JUCE_IOS || JUCE_ANDROID // (64-bit ops will compile but not link on these mobile OSes) #if JUCE_IOS || JUCE_ANDROID // (64-bit ops will compile but not link on these mobile OSes)
@@ -258,6 +258,7 @@ private:
#endif #endif
#endif #endif
#if JUCE_MSVC #if JUCE_MSVC
#pragma warning (push) #pragma warning (push)
#pragma warning (disable: 4311) // (truncation warning) #pragma warning (disable: 4311) // (truncation warning)
@@ -267,7 +268,7 @@ private:
template <typename Type> template <typename Type>
inline Type Atomic<Type>::get() const noexcept inline Type Atomic<Type>::get() const noexcept
{ {
#if JUCE_ATOMICS_MAC
#if JUCE_ATOMICS_MAC_LEGACY
return sizeof (Type) == 4 ? castFrom32Bit ((int32) OSAtomicAdd32Barrier ((int32_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)) return sizeof (Type) == 4 ? castFrom32Bit ((int32) OSAtomicAdd32Barrier ((int32_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value))
: castFrom64Bit ((int64) OSAtomicAdd64Barrier ((int64_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value)); : castFrom64Bit ((int64) OSAtomicAdd64Barrier ((int64_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value));
#elif JUCE_ATOMICS_WINDOWS #elif JUCE_ATOMICS_WINDOWS
@@ -282,7 +283,7 @@ inline Type Atomic<Type>::get() const noexcept
template <typename Type> template <typename Type>
inline Type Atomic<Type>::exchange (const Type newValue) noexcept inline Type Atomic<Type>::exchange (const Type newValue) noexcept
{ {
#if JUCE_ATOMICS_MAC || JUCE_ATOMICS_GCC
#if JUCE_ATOMICS_MAC_LEGACY || JUCE_ATOMICS_GCC
Type currentVal = value; Type currentVal = value;
while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; } while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
return currentVal; return currentVal;
@@ -295,7 +296,7 @@ inline Type Atomic<Type>::exchange (const Type newValue) noexcept
template <typename Type> template <typename Type>
inline Type Atomic<Type>::operator+= (const Type amountToAdd) noexcept inline Type Atomic<Type>::operator+= (const Type amountToAdd) noexcept
{ {
#if JUCE_ATOMICS_MAC
#if JUCE_ATOMICS_MAC_LEGACY
return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amountToAdd), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amountToAdd), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); : (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS #elif JUCE_ATOMICS_WINDOWS
@@ -315,35 +316,37 @@ inline Type Atomic<Type>::operator-= (const Type amountToSubtract) noexcept
template <typename Type> template <typename Type>
inline Type Atomic<Type>::operator++() noexcept inline Type Atomic<Type>::operator++() noexcept
{ {
#if JUCE_ATOMICS_MAC
#if JUCE_ATOMICS_MAC_LEGACY
return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicIncrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); : (Type) OSAtomicIncrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS #elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value)
: (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_GCC #elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, 1);
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) 1)
: (Type) __sync_add_and_fetch ((int64_t*) &value, 1);
#endif #endif
} }
template <typename Type> template <typename Type>
inline Type Atomic<Type>::operator--() noexcept inline Type Atomic<Type>::operator--() noexcept
{ {
#if JUCE_ATOMICS_MAC
#if JUCE_ATOMICS_MAC_LEGACY
return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicDecrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); : (Type) OSAtomicDecrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS #elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value)
: (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_GCC #elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, -1);
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) -1)
: (Type) __sync_add_and_fetch ((int64_t*) &value, -1);
#endif #endif
} }
template <typename Type> template <typename Type>
inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept
{ {
#if JUCE_ATOMICS_MAC
#if JUCE_ATOMICS_MAC_LEGACY
return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
: OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); : OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS #elif JUCE_ATOMICS_WINDOWS
@@ -357,7 +360,7 @@ inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type val
template <typename Type> template <typename Type>
inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept
{ {
#if JUCE_ATOMICS_MAC
#if JUCE_ATOMICS_MAC_LEGACY
for (;;) // Annoying workaround for only having a bool CAS operation.. for (;;) // Annoying workaround for only having a bool CAS operation..
{ {
if (compareAndSetBool (newValue, valueToCompare)) if (compareAndSetBool (newValue, valueToCompare))
@@ -380,7 +383,7 @@ inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type va
template <typename Type> template <typename Type>
inline void Atomic<Type>::memoryBarrier() noexcept inline void Atomic<Type>::memoryBarrier() noexcept
{ {
#if JUCE_ATOMICS_MAC
#if JUCE_ATOMICS_MAC_LEGACY
OSMemoryBarrier(); OSMemoryBarrier();
#elif JUCE_ATOMICS_GCC #elif JUCE_ATOMICS_GCC
__sync_synchronize(); __sync_synchronize();


+ 0
- 1
source/modules/juce_core/misc/juce_Uuid.cpp View File

@@ -26,7 +26,6 @@
============================================================================== ==============================================================================
*/ */
Uuid::Uuid() Uuid::Uuid()
{ {
Random r; Random r;


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

@@ -80,7 +80,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
break; break;
} }
return File::nonexistent;
return File();
} }
bool File::moveToTrash() const bool File::moveToTrash() const


+ 4
- 0
source/modules/juce_core/native/juce_android_Network.cpp View File

@@ -87,6 +87,10 @@ public:
LocalRef<jobject> responseHeaderBuffer (env->NewObject (StringBuffer, StringBuffer.constructor)); LocalRef<jobject> responseHeaderBuffer (env->NewObject (StringBuffer, StringBuffer.constructor));
// Annoyingly, the android HTTP functions will choke on this call if you try to do it on the message
// thread. You'll need to move your networking code to a background thread to keep it happy..
jassert (Thread::getCurrentThread() != nullptr);
stream = GlobalRef (env->CallStaticObjectMethod (JuceAppActivity, stream = GlobalRef (env->CallStaticObjectMethod (JuceAppActivity,
JuceAppActivity.createHTTPStream, JuceAppActivity.createHTTPStream,
javaString (address).get(), javaString (address).get(),


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

@@ -192,6 +192,11 @@ String SystemStats::getOperatingSystemName()
return "Android " + AndroidStatsHelpers::getSystemProperty ("os.version"); return "Android " + AndroidStatsHelpers::getSystemProperty ("os.version");
} }
String SystemStats::getDeviceDescription()
{
return String::empty;
}
bool SystemStats::isOperatingSystem64Bit() bool SystemStats::isOperatingSystem64Bit()
{ {
#if JUCE_64BIT #if JUCE_64BIT


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

@@ -72,7 +72,7 @@ bool File::isOnRemovableDrive() const
String File::getVersion() const String File::getVersion() const
{ {
return String::empty; // xxx not yet implemented
return String(); // xxx not yet implemented
} }
//============================================================================== //==============================================================================
@@ -115,7 +115,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
if (struct passwd* const pw = getpwuid (getuid())) if (struct passwd* const pw = getpwuid (getuid()))
return File (CharPointer_UTF8 (pw->pw_dir)); return File (CharPointer_UTF8 (pw->pw_dir));
return File::nonexistent;
return File();
} }
case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~"); case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~");
@@ -163,7 +163,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
break; break;
} }
return File::nonexistent;
return File();
} }
//============================================================================== //==============================================================================


+ 3
- 3
source/modules/juce_core/native/juce_linux_Network.cpp View File

@@ -309,7 +309,7 @@ private:
{ {
char c = 0; char c = 0;
if (read (&c, 1) != 1) if (read (&c, 1) != 1)
return String::empty;
return String();
buffer.writeByte (c); buffer.writeByte (c);
@@ -324,7 +324,7 @@ private:
if (header.startsWithIgnoreCase ("HTTP/")) if (header.startsWithIgnoreCase ("HTTP/"))
return header; return header;
return String::empty;
return String();
} }
static void writeValueIfNotPresent (MemoryOutputStream& dest, const String& headers, const String& key, const String& value) static void writeValueIfNotPresent (MemoryOutputStream& dest, const String& headers, const String& key, const String& value)
@@ -432,7 +432,7 @@ private:
if (lines[i].startsWithIgnoreCase (itemName)) if (lines[i].startsWithIgnoreCase (itemName))
return lines[i].substring (itemName.length()).trim(); return lines[i].substring (itemName.length()).trim();
return String::empty;
return String();
} }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream)


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

@@ -42,6 +42,11 @@ String SystemStats::getOperatingSystemName()
return "Linux"; return "Linux";
} }
String SystemStats::getDeviceDescription()
{
return String();
}
bool SystemStats::isOperatingSystem64Bit() bool SystemStats::isOperatingSystem64Bit()
{ {
#if JUCE_64BIT #if JUCE_64BIT
@@ -64,7 +69,7 @@ namespace LinuxStatsHelpers
if (lines[i].startsWithIgnoreCase (key)) if (lines[i].startsWithIgnoreCase (key))
return lines[i].fromFirstOccurrenceOf (":", false, false).trim(); return lines[i].fromFirstOccurrenceOf (":", false, false).trim();
return String::empty;
return String();
} }
} }
@@ -102,7 +107,7 @@ String SystemStats::getLogonName()
if (struct passwd* const pw = getpwuid (getuid())) if (struct passwd* const pw = getpwuid (getuid()))
return CharPointer_UTF8 (pw->pw_name); return CharPointer_UTF8 (pw->pw_name);
return String::empty;
return String();
} }
String SystemStats::getFullUserName() String SystemStats::getFullUserName()
@@ -116,7 +121,7 @@ String SystemStats::getComputerName()
if (gethostname (name, sizeof (name) - 1) == 0) if (gethostname (name, sizeof (name) - 1) == 0)
return name; return name;
return String::empty;
return String();
} }
static String getLocaleValue (nl_item key) static String getLocaleValue (nl_item key)


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

@@ -257,7 +257,7 @@ File File::getSpecialLocation (const SpecialLocationType type)
return File (resultPath.convertToPrecomposedUnicode()); return File (resultPath.convertToPrecomposedUnicode());
} }
return File::nonexistent;
return File();
} }
//============================================================================== //==============================================================================
@@ -271,7 +271,7 @@ String File::getVersion() const
return nsStringToJuce (name); return nsStringToJuce (name);
} }
return String::empty;
return String();
} }
//============================================================================== //==============================================================================
@@ -356,7 +356,7 @@ public:
return false; return false;
[enumerator skipDescendents]; [enumerator skipDescendents];
filenameFound = nsStringToJuce (file);
filenameFound = nsStringToJuce (file).convertToPrecomposedUnicode();
if (wildcardUTF8 == nullptr) if (wildcardUTF8 == nullptr)
wildcardUTF8 = wildCard.toUTF8(); wildcardUTF8 = wildCard.toUTF8();


+ 1
- 1
source/modules/juce_core/native/juce_mac_Strings.mm View File

@@ -29,7 +29,7 @@
String String::fromCFString (CFStringRef cfString) String String::fromCFString (CFStringRef cfString)
{ {
if (cfString == 0) if (cfString == 0)
return String::empty;
return String();
CFRange range = { 0, CFStringGetLength (cfString) }; CFRange range = { 0, CFStringGetLength (cfString) };
HeapBlock <UniChar> u ((size_t) range.length + 1); HeapBlock <UniChar> u ((size_t) range.length + 1);


+ 12
- 3
source/modules/juce_core/native/juce_mac_SystemStats.mm View File

@@ -124,7 +124,7 @@ SystemStats::OperatingSystemType SystemStats::getOperatingSystemType()
return iOS; return iOS;
#else #else
StringArray parts; StringArray parts;
parts.addTokens (getOSXVersion(), ".", String::empty);
parts.addTokens (getOSXVersion(), ".", String());
jassert (parts[0].getIntValue() == 10); jassert (parts[0].getIntValue() == 10);
const int major = parts[1].getIntValue(); const int major = parts[1].getIntValue();
@@ -143,6 +143,15 @@ String SystemStats::getOperatingSystemName()
#endif #endif
} }
String SystemStats::getDeviceDescription()
{
#if JUCE_IOS
return nsStringToJuce ([[UIDevice currentDevice] model]);
#else
return String();
#endif
}
bool SystemStats::isOperatingSystem64Bit() bool SystemStats::isOperatingSystem64Bit()
{ {
#if JUCE_IOS #if JUCE_IOS
@@ -173,7 +182,7 @@ String SystemStats::getCpuVendor()
return String (reinterpret_cast <const char*> (vendor), 12); return String (reinterpret_cast <const char*> (vendor), 12);
#else #else
return String::empty;
return String();
#endif #endif
} }
@@ -209,7 +218,7 @@ String SystemStats::getComputerName()
if (gethostname (name, sizeof (name) - 1) == 0) if (gethostname (name, sizeof (name) - 1) == 0)
return String (name).upToLastOccurrenceOf (".local", false, true); return String (name).upToLastOccurrenceOf (".local", false, true);
return String::empty;
return String();
} }
static String getLocaleValue (CFStringRef key) static String getLocaleValue (CFStringRef key)


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

@@ -194,7 +194,12 @@ bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
pimpl = new Pimpl (File::getSpecialLocation (File::tempDirectory) pimpl = new Pimpl (File::getSpecialLocation (File::tempDirectory)
.getChildFile (File::createLegalFileName (pipeName)).getFullPathName(), createPipe); .getChildFile (File::createLegalFileName (pipeName)).getFullPathName(), createPipe);
#else #else
pimpl = new Pimpl ("/tmp/" + File::createLegalFileName (pipeName), createPipe);
String file (pipeName);
if (! File::isAbsolutePath (file))
file = "/tmp/" + File::createLegalFileName (file);
pimpl = new Pimpl (file, createPipe);
#endif #endif
if (createPipe && ! pimpl->createFifos()) if (createPipe && ! pimpl->createFifos())


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

@@ -636,7 +636,7 @@ String File::getVolumeLabel() const
} }
#endif #endif
return String::empty;
return String();
} }
int File::getVolumeSerialNumber() const int File::getVolumeSerialNumber() const


+ 4
- 2
source/modules/juce_core/native/juce_win32_Files.cpp View File

@@ -93,7 +93,7 @@ namespace WindowsFileHelpers
if (SHGetSpecialFolderPath (0, path, type, FALSE)) if (SHGetSpecialFolderPath (0, path, type, FALSE))
return File (String (path)); return File (String (path));
return File::nonexistent;
return File();
} }
File getModuleFileName (HINSTANCE moduleHandle) File getModuleFileName (HINSTANCE moduleHandle)
@@ -542,7 +542,7 @@ File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type)
default: default:
jassertfalse; // unknown type? jassertfalse; // unknown type?
return File::nonexistent;
return File();
} }
return WindowsFileHelpers::getSpecialFolderPath (csidlType); return WindowsFileHelpers::getSpecialFolderPath (csidlType);
@@ -630,6 +630,8 @@ bool File::createLink (const String& description, const File& linkFileToCreate)
ComSmartPtr<IShellLink> shellLink; ComSmartPtr<IShellLink> shellLink;
ComSmartPtr<IPersistFile> persistFile; ComSmartPtr<IPersistFile> persistFile;
CoInitialize (0);
return SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink)) return SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink))
&& SUCCEEDED (shellLink->SetPath (getFullPathName().toWideCharPointer())) && SUCCEEDED (shellLink->SetPath (getFullPathName().toWideCharPointer()))
&& SUCCEEDED (shellLink->SetDescription (description.toWideCharPointer())) && SUCCEEDED (shellLink->SetDescription (description.toWideCharPointer()))


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

@@ -197,6 +197,11 @@ String SystemStats::getOperatingSystemName()
return name; return name;
} }
String SystemStats::getDeviceDescription()
{
return String::empty;
}
bool SystemStats::isOperatingSystem64Bit() bool SystemStats::isOperatingSystem64Bit()
{ {
#if JUCE_64BIT #if JUCE_64BIT


+ 1
- 1
source/modules/juce_core/network/juce_IPAddress.cpp View File

@@ -55,7 +55,7 @@ IPAddress::IPAddress (uint32 n) noexcept
IPAddress::IPAddress (const String& adr) IPAddress::IPAddress (const String& adr)
{ {
StringArray tokens; StringArray tokens;
tokens.addTokens (adr, ".", String::empty);
tokens.addTokens (adr, ".", String());
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
address[i] = (uint8) tokens[i].getIntValue(); address[i] = (uint8) tokens[i].getIntValue();


+ 4
- 4
source/modules/juce_core/network/juce_MACAddress.h View File

@@ -51,10 +51,10 @@ public:
MACAddress(); MACAddress();
/** Creates a copy of another address. */ /** Creates a copy of another address. */
MACAddress (const MACAddress& other);
MACAddress (const MACAddress&);
/** Creates a copy of another address. */ /** Creates a copy of another address. */
MACAddress& operator= (const MACAddress& other);
MACAddress& operator= (const MACAddress&);
/** Creates an address from 6 bytes. */ /** Creates an address from 6 bytes. */
explicit MACAddress (const uint8 bytes[6]); explicit MACAddress (const uint8 bytes[6]);
@@ -75,8 +75,8 @@ public:
/** Returns true if this address is null (00-00-00-00-00-00). */ /** Returns true if this address is null (00-00-00-00-00-00). */
bool isNull() const noexcept; bool isNull() const noexcept;
bool operator== (const MACAddress& other) const noexcept;
bool operator!= (const MACAddress& other) const noexcept;
bool operator== (const MACAddress&) const noexcept;
bool operator!= (const MACAddress&) const noexcept;
//============================================================================== //==============================================================================
private: private:


+ 2
- 2
source/modules/juce_core/network/juce_Socket.cpp View File

@@ -386,7 +386,7 @@ void StreamingSocket::close()
::close (handle); ::close (handle);
#endif #endif
hostName = String::empty;
hostName.clear();
portNumber = 0; portNumber = 0;
handle = -1; handle = -1;
isListener = false; isListener = false;
@@ -506,7 +506,7 @@ void DatagramSocket::close()
::close (handle); ::close (handle);
#endif #endif
hostName = String::empty;
hostName.clear();
portNumber = 0; portNumber = 0;
handle = -1; handle = -1;
} }


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

@@ -146,7 +146,7 @@ public:
@see waitForNextConnection @see waitForNextConnection
*/ */
bool createListener (int portNumber, const String& localHostName = String::empty);
bool createListener (int portNumber, const String& localHostName = String());
/** When in "listener" mode, this waits for a connection and spawns it as a new /** When in "listener" mode, this waits for a connection and spawns it as a new
socket. socket.


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

@@ -181,7 +181,7 @@ namespace URLHelpers
<< "\"; filename=\"" << file.getFileName() << "\"\r\n"; << "\"; filename=\"" << file.getFileName() << "\"\r\n";
const String mimeType (url.getMimeTypesOfUploadFiles() const String mimeType (url.getMimeTypesOfUploadFiles()
.getValue (paramName, String::empty));
.getValue (paramName, String()));
if (mimeType.isNotEmpty()) if (mimeType.isNotEmpty())
data << "Content-Type: " << mimeType << "\r\n"; data << "Content-Type: " << mimeType << "\r\n";
@@ -253,7 +253,7 @@ String URL::getSubPath() const
{ {
const int startOfPath = URLHelpers::findStartOfPath (url); const int startOfPath = URLHelpers::findStartOfPath (url);
return startOfPath <= 0 ? String::empty
return startOfPath <= 0 ? String()
: url.substring (startOfPath); : url.substring (startOfPath);
} }
@@ -363,7 +363,7 @@ String URL::readEntireTextStream (const bool usePostCommand) const
if (in != nullptr) if (in != nullptr)
return in->readEntireStreamAsString(); return in->readEntireStreamAsString();
return String::empty;
return String();
} }
XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const
@@ -470,5 +470,5 @@ bool URL::launchInDefaultBrowser() const
if (u.containsChar ('@') && ! u.containsChar (':')) if (u.containsChar ('@') && ! u.containsChar (':'))
u = "mailto:" + u; u = "mailto:" + u;
return Process::openDocument (u, String::empty);
return Process::openDocument (u, String());
} }

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

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


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

@@ -34,9 +34,9 @@
See also SystemStats::getJUCEVersion() for a string version. See also SystemStats::getJUCEVersion() for a string version.
*/ */
#define JUCE_MAJOR_VERSION 2
#define JUCE_MINOR_VERSION 1
#define JUCE_BUILDNUMBER 7
#define JUCE_MAJOR_VERSION 3
#define JUCE_MINOR_VERSION 0
#define JUCE_BUILDNUMBER 2
/** Current Juce version number. /** Current Juce version number.


+ 7
- 2
source/modules/juce_core/system/juce_SystemStats.h View File

@@ -83,8 +83,7 @@ public:
*/ */
static String getOperatingSystemName(); static String getOperatingSystemName();
/** Returns true if the OS is 64-bit, or false for a 32-bit OS.
*/
/** Returns true if the OS is 64-bit, or false for a 32-bit OS. */
static bool isOperatingSystem64Bit(); static bool isOperatingSystem64Bit();
/** Returns an environment variable. /** Returns an environment variable.
@@ -122,6 +121,12 @@ public:
*/ */
static String getDisplayLanguage(); static String getDisplayLanguage();
/** This will attempt to return some kind of string describing the device.
If no description is available, it'll just return an empty string. You may
want to use this for things like determining the type of phone/iPad, etc.
*/
static String getDeviceDescription();
//============================================================================== //==============================================================================
// CPU and memory information.. // CPU and memory information..


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

@@ -441,7 +441,7 @@ public:
/** Returns true if this data contains a valid string in this encoding. */ /** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead) static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{ {
maxBytesToRead /= sizeof (CharType);
maxBytesToRead /= (int) sizeof (CharType);
while (--maxBytesToRead >= 0 && *dataToTest != 0) while (--maxBytesToRead >= 0 && *dataToTest != 0)
{ {


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

@@ -355,7 +355,7 @@ public:
/** Returns true if this data contains a valid string in this encoding. */ /** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead) static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{ {
maxBytesToRead /= sizeof (CharType);
maxBytesToRead /= (int) sizeof (CharType);
while (--maxBytesToRead >= 0 && *dataToTest != 0) while (--maxBytesToRead >= 0 && *dataToTest != 0)
if (! canRepresent (*dataToTest++)) if (! canRepresent (*dataToTest++))


+ 3
- 10
source/modules/juce_core/text/juce_CharPointer_UTF8.h View File

@@ -171,11 +171,12 @@ public:
while (--numExtraValues >= 0) while (--numExtraValues >= 0)
{ {
const uint32 nextByte = (uint32) (uint8) *data++;
const uint32 nextByte = (uint32) (uint8) *data;
if ((nextByte & 0xc0) != 0x80) if ((nextByte & 0xc0) != 0x80)
break; break;
++data;
n <<= 6; n <<= 6;
n |= (nextByte & 0x3f); n |= (nextByte & 0x3f);
} }
@@ -248,16 +249,8 @@ public:
if ((n & 0x80) != 0) if ((n & 0x80) != 0)
{ {
uint32 bit = 0x40;
while ((n & bit) != 0)
{
while ((*d & 0xc0) == 0x80)
++d; ++d;
bit >>= 1;
if (bit == 0)
break; // illegal utf-8 sequence
}
} }
else if (n == 0) else if (n == 0)
break; break;


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

@@ -594,8 +594,8 @@ public:
/** Returns a pointer to the first character in the string which is found in /** Returns a pointer to the first character in the string which is found in
the breakCharacters string. the breakCharacters string.
*/ */
template <typename Type>
static Type findEndOfToken (Type text, const Type breakCharacters, const Type quoteCharacters)
template <typename Type, typename BreakType>
static Type findEndOfToken (Type text, const BreakType breakCharacters, const Type quoteCharacters)
{ {
juce_wchar currentQuoteChar = 0; juce_wchar currentQuoteChar = 0;


+ 30
- 2
source/modules/juce_core/text/juce_LocalisedStrings.cpp View File

@@ -36,6 +36,21 @@ LocalisedStrings::LocalisedStrings (const File& fileToLoad, bool ignoreCase)
loadFromText (fileToLoad.loadFileAsString(), ignoreCase); loadFromText (fileToLoad.loadFileAsString(), ignoreCase);
} }
LocalisedStrings::LocalisedStrings (const LocalisedStrings& other)
: languageName (other.languageName), countryCodes (other.countryCodes),
translations (other.translations), fallback (createCopyIfNotNull (other.fallback.get()))
{
}
LocalisedStrings& LocalisedStrings::operator= (const LocalisedStrings& other)
{
languageName = other.languageName;
countryCodes = other.countryCodes;
translations = other.translations;
fallback = createCopyIfNotNull (other.fallback.get());
return *this;
}
LocalisedStrings::~LocalisedStrings() LocalisedStrings::~LocalisedStrings()
{ {
} }
@@ -43,11 +58,17 @@ LocalisedStrings::~LocalisedStrings()
//============================================================================== //==============================================================================
String LocalisedStrings::translate (const String& text) const String LocalisedStrings::translate (const String& text) const
{ {
if (fallback != nullptr && ! translations.containsKey (text))
return fallback->translate (text);
return translations.getValue (text, text); return translations.getValue (text, text);
} }
String LocalisedStrings::translate (const String& text, const String& resultIfNotFound) const String LocalisedStrings::translate (const String& text, const String& resultIfNotFound) const
{ {
if (fallback != nullptr && ! translations.containsKey (text))
return fallback->translate (text, resultIfNotFound);
return translations.getValue (text, resultIfNotFound); return translations.getValue (text, resultIfNotFound);
} }
@@ -73,7 +94,7 @@ namespace
SpinLock currentMappingsLock; SpinLock currentMappingsLock;
ScopedPointer<LocalisedStrings> currentMappings; ScopedPointer<LocalisedStrings> currentMappings;
int findCloseQuote (const String& text, int startPos)
static int findCloseQuote (const String& text, int startPos)
{ {
juce_wchar lastChar = 0; juce_wchar lastChar = 0;
String::CharPointerType t (text.getCharPointer() + startPos); String::CharPointerType t (text.getCharPointer() + startPos);
@@ -92,7 +113,7 @@ namespace
return startPos; return startPos;
} }
String unescapeString (const String& s)
static String unescapeString (const String& s)
{ {
return s.replace ("\\\"", "\"") return s.replace ("\\\"", "\"")
.replace ("\\\'", "\'") .replace ("\\\'", "\'")
@@ -141,6 +162,8 @@ void LocalisedStrings::loadFromText (const String& fileContents, bool ignoreCase
countryCodes.removeEmptyStrings(); countryCodes.removeEmptyStrings();
} }
} }
translations.minimiseStorageOverheads();
} }
void LocalisedStrings::addStrings (const LocalisedStrings& other) void LocalisedStrings::addStrings (const LocalisedStrings& other)
@@ -151,6 +174,11 @@ void LocalisedStrings::addStrings (const LocalisedStrings& other)
translations.addArray (other.translations); translations.addArray (other.translations);
} }
void LocalisedStrings::setFallback (LocalisedStrings* f)
{
fallback = f;
}
//============================================================================== //==============================================================================
void LocalisedStrings::setCurrentMappings (LocalisedStrings* newTranslations) void LocalisedStrings::setCurrentMappings (LocalisedStrings* newTranslations)
{ {


+ 14
- 5
source/modules/juce_core/text/juce_LocalisedStrings.h View File

@@ -82,16 +82,17 @@ public:
When you create one of these, you can call setCurrentMappings() to make it When you create one of these, you can call setCurrentMappings() to make it
the set of mappings that the system's using. the set of mappings that the system's using.
*/ */
LocalisedStrings (const String& fileContents,
bool ignoreCaseOfKeys);
LocalisedStrings (const String& fileContents, bool ignoreCaseOfKeys);
/** Creates a set of translations from a file. /** Creates a set of translations from a file.
When you create one of these, you can call setCurrentMappings() to make it When you create one of these, you can call setCurrentMappings() to make it
the set of mappings that the system's using. the set of mappings that the system's using.
*/ */
LocalisedStrings (const File& fileToLoad,
bool ignoreCaseOfKeys);
LocalisedStrings (const File& fileToLoad, bool ignoreCaseOfKeys);
LocalisedStrings (const LocalisedStrings&);
LocalisedStrings& operator= (const LocalisedStrings&);
/** Destructor. */ /** Destructor. */
~LocalisedStrings(); ~LocalisedStrings();
@@ -100,7 +101,7 @@ public:
/** Selects the current set of mappings to be used by the system. /** Selects the current set of mappings to be used by the system.
The object you pass in will be automatically deleted when no longer needed, so The object you pass in will be automatically deleted when no longer needed, so
don't keep a pointer to it. You can also pass in zero to remove the current
don't keep a pointer to it. You can also pass in nullptr to remove the current
mappings. mappings.
See also the TRANS() macro, which uses the current set to do its translation. See also the TRANS() macro, which uses the current set to do its translation.
@@ -183,11 +184,19 @@ public:
*/ */
void addStrings (const LocalisedStrings&); void addStrings (const LocalisedStrings&);
/** Gives this object a set of strings to use as a fallback if a string isn't found.
The object that is passed-in will be owned and deleted by this object
when no longer needed. It can be nullptr to clear the existing fallback object.
*/
void setFallback (LocalisedStrings* fallbackStrings);
private: private:
//============================================================================== //==============================================================================
String languageName; String languageName;
StringArray countryCodes; StringArray countryCodes;
StringPairArray translations; StringPairArray translations;
ScopedPointer<LocalisedStrings> fallback;
friend struct ContainerDeletePolicy<LocalisedStrings>;
void loadFromText (const String&, bool ignoreCase); void loadFromText (const String&, bool ignoreCase);


+ 62
- 15
source/modules/juce_core/text/juce_String.cpp View File

@@ -259,6 +259,12 @@ void String::swapWith (String& other) noexcept
std::swap (text, other.text); std::swap (text, other.text);
} }
void String::clear() noexcept
{
StringHolder::release (text);
text = &(emptyString.text);
}
String& String::operator= (const String& other) noexcept String& String::operator= (const String& other) noexcept
{ {
StringHolder::retain (other.text); StringHolder::retain (other.text);
@@ -307,6 +313,10 @@ String::String (const char* const t)
you use UTF-8 with escape characters in your source code to represent extended characters, you use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent these strings in a way that isn't dependent on because there's no other way to represent these strings in a way that isn't dependent on
the compiler, source code editor and platform. the compiler, source code editor and platform.
Note that the Introjucer has a handy string literal generator utility that will convert
any unicode string to a valid C++ string literal, creating ascii escape sequences that will
work in any compiler.
*/ */
jassert (t == nullptr || CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max())); jassert (t == nullptr || CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max()));
} }
@@ -326,6 +336,10 @@ String::String (const char* const t, const size_t maxChars)
you use UTF-8 with escape characters in your source code to represent extended characters, you use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent these strings in a way that isn't dependent on because there's no other way to represent these strings in a way that isn't dependent on
the compiler, source code editor and platform. the compiler, source code editor and platform.
Note that the Introjucer has a handy string literal generator utility that will convert
any unicode string to a valid C++ string literal, creating ascii escape sequences that will
work in any compiler.
*/ */
jassert (t == nullptr || CharPointer_ASCII::isValidString (t, (int) maxChars)); jassert (t == nullptr || CharPointer_ASCII::isValidString (t, (int) maxChars));
} }
@@ -419,7 +433,8 @@ namespace NumberToStringConverters
{ {
explicit StackArrayStream (char* d) explicit StackArrayStream (char* d)
{ {
imbue (std::locale::classic());
static const std::locale classicLocale (std::locale::classic());
imbue (classicLocale);
setp (d, d + charsNeededForDouble); setp (d, d + charsNeededForDouble);
} }
@@ -684,23 +699,28 @@ String& String::operator+= (const juce_wchar ch)
String& String::operator+= (const int number) String& String::operator+= (const int number)
{ {
char buffer [16]; char buffer [16];
char* const end = buffer + numElementsInArray (buffer);
char* const start = NumberToStringConverters::numberToString (end, number);
char* end = buffer + numElementsInArray (buffer);
char* start = NumberToStringConverters::numberToString (end, number);
const int numExtraChars = (int) (end - start);
if (numExtraChars > 0)
{
const size_t byteOffsetOfNull = getByteOffsetOfEnd();
const size_t newBytesNeeded = sizeof (CharPointerType::CharType) + byteOffsetOfNull
+ sizeof (CharPointerType::CharType) * (size_t) numExtraChars;
text = StringHolder::makeUniqueWithByteSize (text, newBytesNeeded);
#if (JUCE_STRING_UTF_TYPE == 8)
appendCharPointer (CharPointerType (start), CharPointerType (end));
#else
appendCharPointer (CharPointer_ASCII (start), CharPointer_ASCII (end));
#endif
return *this;
}
CharPointerType newEnd (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull));
newEnd.writeWithCharLimit (CharPointer_ASCII (start), numExtraChars);
}
String& String::operator+= (int64 number)
{
char buffer [32];
char* end = buffer + numElementsInArray (buffer);
char* start = NumberToStringConverters::numberToString (end, number);
#if (JUCE_STRING_UTF_TYPE == 8)
appendCharPointer (CharPointerType (start), CharPointerType (end));
#else
appendCharPointer (CharPointer_ASCII (start), CharPointer_ASCII (end));
#endif
return *this; return *this;
} }
@@ -737,6 +757,7 @@ JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const long number)
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const int64 number) { return s1 += String (number); } JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const int64 number) { return s1 += String (number); }
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const float number) { return s1 += String (number); } JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const float number) { return s1 += String (number); }
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const double number) { return s1 += String (number); } JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const double number) { return s1 += String (number); }
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const uint64 number) { return s1 += String (number); }
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text) JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text)
{ {
@@ -2192,6 +2213,10 @@ public:
s2 << ((int) 4) << ((short) 5) << "678" << L"9" << '0'; s2 << ((int) 4) << ((short) 5) << "678" << L"9" << '0';
s2 += "xyz"; s2 += "xyz";
expect (s2 == "1234567890xyz"); expect (s2 == "1234567890xyz");
s2 += (int) 123;
expect (s2 == "1234567890xyz123");
s2 += (int64) 123;
expect (s2 == "1234567890xyz123123");
beginTest ("Numeric conversions"); beginTest ("Numeric conversions");
expect (String::empty.getIntValue() == 0); expect (String::empty.getIntValue() == 0);
@@ -2388,6 +2413,28 @@ public:
expectEquals (toks.size(), 3); expectEquals (toks.size(), 3);
expectEquals (toks.joinIntoString ("-"), String ("x-'y,z'-")); expectEquals (toks.joinIntoString ("-"), String ("x-'y,z'-"));
} }
{
beginTest ("var");
var v1 = 0;
var v2 = 0.1;
var v3 = "0.1";
var v4 = (int64) 0;
var v5 = 0.0;
expect (! v2.equals (v1));
expect (! v1.equals (v2));
expect (v2.equals (v3));
expect (v3.equals (v2));
expect (! v3.equals (v1));
expect (! v1.equals (v3));
expect (v1.equals (v4));
expect (v4.equals (v1));
expect (v5.equals (v4));
expect (v4.equals (v5));
expect (! v2.equals (v4));
expect (! v4.equals (v2));
}
} }
}; };


+ 39
- 24
source/modules/juce_core/text/juce_String.h View File

@@ -204,6 +204,8 @@ public:
String& operator+= (const wchar_t* textToAppend); String& operator+= (const wchar_t* textToAppend);
/** Appends a decimal number at the end of this string. */ /** Appends a decimal number at the end of this string. */
String& operator+= (int numberToAppend); String& operator+= (int numberToAppend);
/** Appends a decimal number at the end of this string. */
String& operator+= (int64 numberToAppend);
/** Appends a character at the end of this string. */ /** Appends a character at the end of this string. */
String& operator+= (char characterToAppend); String& operator+= (char characterToAppend);
/** Appends a character at the end of this string. */ /** Appends a character at the end of this string. */
@@ -228,6 +230,32 @@ public:
void appendCharPointer (const CharPointerType startOfTextToAppend, void appendCharPointer (const CharPointerType startOfTextToAppend,
const CharPointerType endOfTextToAppend); const CharPointerType endOfTextToAppend);
/** Appends a string to the end of this one.
@param startOfTextToAppend the start of the string to add. This must not be a nullptr
@param endOfTextToAppend the end of the string to add. This must not be a nullptr
*/
template <class CharPointer>
void appendCharPointer (const CharPointer startOfTextToAppend,
const CharPointer endOfTextToAppend)
{
jassert (startOfTextToAppend.getAddress() != nullptr && endOfTextToAppend.getAddress() != nullptr);
size_t extraBytesNeeded = 0, numChars = 1;
for (CharPointer t (startOfTextToAppend); t != endOfTextToAppend && ! t.isEmpty(); ++numChars)
extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance());
if (extraBytesNeeded > 0)
{
const size_t byteOffsetOfNull = getByteOffsetOfEnd();
preallocateBytes (byteOffsetOfNull + extraBytesNeeded);
CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull))
.writeWithCharLimit (startOfTextToAppend, (int) numChars);
}
}
/** Appends a string to the end of this one. */ /** Appends a string to the end of this one. */
void appendCharPointer (const CharPointerType textToAppend); void appendCharPointer (const CharPointerType textToAppend);
@@ -241,21 +269,18 @@ public:
{ {
if (textToAppend.getAddress() != nullptr) if (textToAppend.getAddress() != nullptr)
{ {
size_t extraBytesNeeded = 0;
size_t numChars = 0;
size_t extraBytesNeeded = 0, numChars = 1;
for (CharPointer t (textToAppend); numChars < maxCharsToTake && ! t.isEmpty();)
{
for (CharPointer t (textToAppend); numChars <= maxCharsToTake && ! t.isEmpty(); ++numChars)
extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance());
++numChars;
}
if (numChars > 0)
if (extraBytesNeeded > 0)
{ {
const size_t byteOffsetOfNull = getByteOffsetOfEnd(); const size_t byteOffsetOfNull = getByteOffsetOfEnd();
preallocateBytes (byteOffsetOfNull + extraBytesNeeded); preallocateBytes (byteOffsetOfNull + extraBytesNeeded);
CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)).writeWithCharLimit (textToAppend, (int) (numChars + 1));
CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull))
.writeWithCharLimit (textToAppend, (int) numChars);
} }
} }
} }
@@ -264,21 +289,7 @@ public:
template <class CharPointer> template <class CharPointer>
void appendCharPointer (const CharPointer textToAppend) void appendCharPointer (const CharPointer textToAppend)
{ {
if (textToAppend.getAddress() != nullptr)
{
size_t extraBytesNeeded = 0;
for (CharPointer t (textToAppend); ! t.isEmpty();)
extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance());
if (extraBytesNeeded > 0)
{
const size_t byteOffsetOfNull = getByteOffsetOfEnd();
preallocateBytes (byteOffsetOfNull + extraBytesNeeded);
CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)).writeAll (textToAppend);
}
}
appendCharPointer (textToAppend, std::numeric_limits<size_t>::max());
} }
//============================================================================== //==============================================================================
@@ -296,6 +307,9 @@ public:
*/ */
inline bool isNotEmpty() const noexcept { return text[0] != 0; } inline bool isNotEmpty() const noexcept { return text[0] != 0; }
/** Resets this string to be empty. */
void clear() noexcept;
/** Case-insensitive comparison with another string. */ /** Case-insensitive comparison with another string. */
bool equalsIgnoreCase (const String& other) const noexcept; bool equalsIgnoreCase (const String& other) const noexcept;
@@ -1216,7 +1230,6 @@ private:
}; };
explicit String (const PreallocationBytes&); // This constructor preallocates a certain amount of memory explicit String (const PreallocationBytes&); // This constructor preallocates a certain amount of memory
void appendFixedLength (const char* text, int numExtraChars);
size_t getByteOffsetOfEnd() const noexcept; size_t getByteOffsetOfEnd() const noexcept;
JUCE_DEPRECATED (String (const String&, size_t)); JUCE_DEPRECATED (String (const String&, size_t));
@@ -1281,6 +1294,8 @@ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, long number);
/** Appends a decimal number at the end of a string. */ /** Appends a decimal number at the end of a string. */
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int64 number); JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int64 number);
/** Appends a decimal number at the end of a string. */ /** Appends a decimal number at the end of a string. */
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, uint64 number);
/** Appends a decimal number at the end of a string. */
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, float number); JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, float number);
/** Appends a decimal number at the end of a string. */ /** Appends a decimal number at the end of a string. */
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, double number); JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, double number);


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

@@ -293,7 +293,7 @@ String StringArray::joinIntoString (StringRef separator, int start, int numberTo
start = 0; start = 0;
if (start >= last) if (start >= last)
return String::empty;
return String();
if (start == last - 1) if (start == last - 1)
return strings.getReference (start); return strings.getReference (start);


+ 4
- 5
source/modules/juce_core/text/juce_StringArray.h View File

@@ -189,7 +189,6 @@ public:
void insert (int index, const String& stringToAdd); void insert (int index, const String& stringToAdd);
/** Adds a string to the array as long as it's not already in there. /** Adds a string to the array as long as it's not already in there.
The search can optionally be case-insensitive. The search can optionally be case-insensitive.
*/ */
void addIfNotAlreadyThere (const String& stringToAdd, bool ignoreCase = false); void addIfNotAlreadyThere (const String& stringToAdd, bool ignoreCase = false);
@@ -325,7 +324,6 @@ public:
void removeDuplicates (bool ignoreCase); void removeDuplicates (bool ignoreCase);
/** Removes empty strings from the array. /** Removes empty strings from the array.
@param removeWhitespaceStrings if true, strings that only contain whitespace @param removeWhitespaceStrings if true, strings that only contain whitespace
characters will also be removed characters will also be removed
*/ */
@@ -411,11 +409,12 @@ public:
*/ */
void minimiseStorageOverheads(); void minimiseStorageOverheads();
private:
//==============================================================================
/** This is the array holding the actual strings. This is public to allow direct access
to array methods that may not already be provided by the StringArray class.
*/
Array<String> strings; Array<String> strings;
private:
JUCE_LEAK_DETECTOR (StringArray) JUCE_LEAK_DETECTOR (StringArray)
}; };


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

@@ -78,6 +78,11 @@ String StringPairArray::getValue (StringRef key, const String& defaultReturnValu
return defaultReturnValue; return defaultReturnValue;
} }
bool StringPairArray::containsKey (StringRef key) const noexcept
{
return keys.contains (key);
}
void StringPairArray::set (const String& key, const String& value) void StringPairArray::set (const String& key, const String& value)
{ {
const int i = keys.indexOf (key, ignoreCase); const int i = keys.indexOf (key, ignoreCase);


+ 2
- 0
source/modules/juce_core/text/juce_StringPairArray.h View File

@@ -85,6 +85,8 @@ public:
*/ */
String getValue (StringRef, const String& defaultReturnValue) const; String getValue (StringRef, const String& defaultReturnValue) const;
/** Returns true if the given key exists. */
bool containsKey (StringRef key) const noexcept;
/** Returns a list of all keys in the array. */ /** Returns a list of all keys in the array. */
const StringArray& getAllKeys() const noexcept { return keys; } const StringArray& getAllKeys() const noexcept { return keys; }


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

@@ -81,7 +81,7 @@ namespace StringPoolHelpers
String::CharPointerType StringPool::getPooledString (const String& s) String::CharPointerType StringPool::getPooledString (const String& s)
{ {
if (s.isEmpty()) if (s.isEmpty())
return String::empty.getCharPointer();
return String().getCharPointer();
return StringPoolHelpers::getPooledStringFromArray (strings, s, lock); return StringPoolHelpers::getPooledStringFromArray (strings, s, lock);
} }
@@ -89,7 +89,7 @@ String::CharPointerType StringPool::getPooledString (const String& s)
String::CharPointerType StringPool::getPooledString (const char* const s) String::CharPointerType StringPool::getPooledString (const char* const s)
{ {
if (s == nullptr || *s == 0) if (s == nullptr || *s == 0)
return String::empty.getCharPointer();
return String().getCharPointer();
return StringPoolHelpers::getPooledStringFromArray (strings, s, lock); return StringPoolHelpers::getPooledStringFromArray (strings, s, lock);
} }
@@ -97,7 +97,7 @@ String::CharPointerType StringPool::getPooledString (const char* const s)
String::CharPointerType StringPool::getPooledString (const wchar_t* const s) String::CharPointerType StringPool::getPooledString (const wchar_t* const s)
{ {
if (s == nullptr || *s == 0) if (s == nullptr || *s == 0)
return String::empty.getCharPointer();
return String().getCharPointer();
return StringPoolHelpers::getPooledStringFromArray (strings, s, lock); return StringPoolHelpers::getPooledStringFromArray (strings, s, lock);
} }


+ 1
- 1
source/modules/juce_core/threads/juce_Thread.cpp View File

@@ -221,7 +221,7 @@ bool Thread::setPriority (const int newPriority)
const ScopedLock sl (startStopLock); const ScopedLock sl (startStopLock);
if (setThreadPriority (threadHandle, newPriority))
if ((! isThreadRunning()) || setThreadPriority (threadHandle, newPriority))
{ {
threadPriority = newPriority; threadPriority = newPriority;
return true; return true;


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

@@ -210,7 +210,7 @@ public:
will wait for it to finish. will wait for it to finish.
If the timeout period expires before the job finishes running, then the job will be If the timeout period expires before the job finishes running, then the job will be
left in the pool and this will return false. It returns true if the job is sucessfully
left in the pool and this will return false. It returns true if the job is successfully
stopped and removed. stopped and removed.
@param job the job to remove @param job the job to remove
@@ -247,7 +247,7 @@ public:
/** Returns one of the jobs in the queue. /** Returns one of the jobs in the queue.
Note that this can be a very volatile list as jobs might be continuously getting shifted Note that this can be a very volatile list as jobs might be continuously getting shifted
around in the list, and this method may return 0 if the index is currently out-of-range.
around in the list, and this method may return nullptr if the index is currently out-of-range.
*/ */
ThreadPoolJob* getJob (int index) const; ThreadPoolJob* getJob (int index) const;


+ 76
- 40
source/modules/juce_core/time/juce_PerformanceCounter.cpp View File

@@ -26,71 +26,107 @@
============================================================================== ==============================================================================
*/ */
PerformanceCounter::PerformanceCounter (const String& name_,
const int runsPerPrintout,
const File& loggingFile)
: name (name_),
numRuns (0),
runsPerPrint (runsPerPrintout),
totalTime (0),
started (0),
outputFile (loggingFile)
static void appendToFile (const File& f, const String& s)
{ {
if (outputFile != File::nonexistent)
if (f.getFullPathName().isNotEmpty())
{ {
String s ("**** Counter for \"");
s << name_ << "\" started at: "
<< Time::getCurrentTime().toString (true, true)
<< newLine;
FileOutputStream out (f);
outputFile.appendText (s, false, false);
if (! out.failedToOpen())
out << s << newLine;
} }
} }
PerformanceCounter::PerformanceCounter (const String& name, int runsPerPrintout, const File& loggingFile)
: runsPerPrint (runsPerPrintout), startTime (0), outputFile (loggingFile)
{
stats.name = name;
appendToFile (outputFile, "**** Counter for \"" + name + "\" started at: " + Time::getCurrentTime().toString (true, true));
}
PerformanceCounter::~PerformanceCounter() PerformanceCounter::~PerformanceCounter()
{ {
printStatistics(); printStatistics();
} }
void PerformanceCounter::start()
PerformanceCounter::Statistics::Statistics() noexcept
: averageSeconds(), maximumSeconds(), minimumSeconds(), totalSeconds(), numRuns()
{ {
started = Time::getHighResolutionTicks();
} }
void PerformanceCounter::stop()
void PerformanceCounter::Statistics::clear() noexcept
{ {
const int64 now = Time::getHighResolutionTicks();
averageSeconds = maximumSeconds = minimumSeconds = totalSeconds = 0;
numRuns = 0;
}
totalTime += 1000.0 * Time::highResolutionTicksToSeconds (now - started);
void PerformanceCounter::Statistics::addResult (double elapsed) noexcept
{
if (numRuns == 0)
{
maximumSeconds = elapsed;
minimumSeconds = elapsed;
}
else
{
maximumSeconds = jmax (maximumSeconds, elapsed);
minimumSeconds = jmin (minimumSeconds, elapsed);
}
if (++numRuns == runsPerPrint)
printStatistics();
++numRuns;
totalSeconds += elapsed;
} }
void PerformanceCounter::printStatistics()
static String timeToString (double secs)
{ {
if (numRuns > 0)
{
String s ("Performance count for \"");
s << name << "\" - average over " << numRuns << " run(s) = ";
return String ((int64) (secs * (secs < 0.01 ? 1000000.0 : 1000.0) + 0.5))
+ (secs < 0.01 ? " microsecs" : " millisecs");
}
const int micros = (int) (totalTime * (1000.0 / numRuns));
String PerformanceCounter::Statistics::toString() const
{
MemoryOutputStream s;
if (micros > 10000)
s << (micros/1000) << " millisecs";
else
s << micros << " microsecs";
s << "Performance count for \"" << name << "\" over " << numRuns << " run(s)" << newLine
<< "Average = " << timeToString (averageSeconds)
<< ", minimum = " << timeToString (minimumSeconds)
<< ", maximum = " << timeToString (maximumSeconds)
<< ", total = " << timeToString (totalSeconds);
s << ", total = " << String (totalTime / 1000, 5) << " seconds";
return s.toString();
}
Logger::outputDebugString (s);
void PerformanceCounter::start() noexcept
{
startTime = Time::getHighResolutionTicks();
}
s << newLine;
bool PerformanceCounter::stop()
{
stats.addResult (Time::highResolutionTicksToSeconds (Time::getHighResolutionTicks() - startTime));
if (outputFile != File::nonexistent)
outputFile.appendText (s, false, false);
if (stats.numRuns < runsPerPrint)
return false;
numRuns = 0;
totalTime = 0;
}
printStatistics();
return true;
}
void PerformanceCounter::printStatistics()
{
const String desc (getStatisticsAndReset().toString());
Logger::outputDebugString (desc);
appendToFile (outputFile, desc);
}
PerformanceCounter::Statistics PerformanceCounter::getStatisticsAndReset()
{
Statistics s (stats);
stats.clear();
if (s.numRuns > 0)
s.averageSeconds = s.totalSeconds / s.numRuns;
return s;
} }

+ 29
- 8
source/modules/juce_core/time/juce_PerformanceCounter.h View File

@@ -65,17 +65,16 @@ public:
*/ */
PerformanceCounter (const String& counterName, PerformanceCounter (const String& counterName,
int runsPerPrintout = 100, int runsPerPrintout = 100,
const File& loggingFile = File::nonexistent);
const File& loggingFile = File());
/** Destructor. */ /** Destructor. */
~PerformanceCounter(); ~PerformanceCounter();
//============================================================================== //==============================================================================
/** Starts timing. /** Starts timing.
@see stop @see stop
*/ */
void start();
void start() noexcept;
/** Stops timing and prints out the results. /** Stops timing and prints out the results.
@@ -84,7 +83,7 @@ public:
@see start @see start
*/ */
void stop();
bool stop();
/** Dumps the current metrics to the debugger output and to a file. /** Dumps the current metrics to the debugger output and to a file.
@@ -94,13 +93,35 @@ public:
*/ */
void printStatistics(); void printStatistics();
/** Holds the current statistics. */
struct Statistics
{
Statistics() noexcept;
void clear() noexcept;
String toString() const;
void addResult (double elapsed) noexcept;
String name;
double averageSeconds;
double maximumSeconds;
double minimumSeconds;
double totalSeconds;
int64 numRuns;
};
/** Returns a copy of the current stats, and resets the internal counter. */
Statistics getStatisticsAndReset();
private: private:
//============================================================================== //==============================================================================
String name;
int numRuns, runsPerPrint;
double totalTime;
int64 started;
Statistics stats;
int64 runsPerPrint, startTime;
File outputFile; File outputFile;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PerformanceCounter)
}; };
#endif // JUCE_PERFORMANCECOUNTER_H_INCLUDED #endif // JUCE_PERFORMANCECOUNTER_H_INCLUDED

+ 1
- 1
source/modules/juce_core/time/juce_Time.cpp View File

@@ -110,7 +110,7 @@ namespace TimeHelpers
const size_t numChars = wcsftime (buffer, bufferSize - 1, format.toUTF32(), tm); const size_t numChars = wcsftime (buffer, bufferSize - 1, format.toUTF32(), tm);
#endif #endif
if (numChars > 0)
if (numChars > 0 || format.isEmpty())
return String (StringType (buffer), return String (StringType (buffer),
StringType (buffer) + (int) numChars); StringType (buffer) + (int) numChars);
} }


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

@@ -210,7 +210,7 @@ XmlElement* XmlDocument::parseDocumentElement (String::CharPointerType textToPar
} }
else else
{ {
lastError = String::empty;
lastError.clear();
ScopedPointer<XmlElement> result (readNextElement (! onlyReadOuterDocumentElement)); ScopedPointer<XmlElement> result (readNextElement (! onlyReadOuterDocumentElement));


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

@@ -285,10 +285,3 @@ bool GZIPDecompressorInputStream::setPosition (int64 newPos)
skipNextBytes (newPos - currentPos); skipNextBytes (newPos - currentPos);
return true; return true;
} }
// (This is used as a way for the zip file code to use the crc32 function without including zlib)
unsigned long juce_crc32 (unsigned long, const unsigned char*, unsigned);
unsigned long juce_crc32 (unsigned long crc, const unsigned char* buf, unsigned len)
{
return zlibNamespace::crc32 (crc, buf, len);
}

+ 36
- 25
source/modules/juce_core/zip/juce_ZipFile.cpp View File

@@ -440,18 +440,13 @@ Result ZipFile::uncompressEntry (const int index,
//============================================================================= //=============================================================================
extern unsigned long juce_crc32 (unsigned long crc, const unsigned char*, unsigned len);
class ZipFile::Builder::Item class ZipFile::Builder::Item
{ {
public: public:
Item (const File& f, const int compression, const String& storedPath)
: file (f),
storedPathname (storedPath.isEmpty() ? f.getFileName() : storedPath),
compressionLevel (compression),
compressedSize (0),
headerStart (0),
checksum (0)
Item (const File& f, InputStream* s, const int compression, const String& storedPath, Time time)
: file (f), stream (s), storedPathname (storedPath),
fileTime (time), compressionLevel (compression),
compressedSize (0), uncompressedSize (0), headerStart (0), checksum (0)
{ {
} }
@@ -500,51 +495,58 @@ public:
private: private:
const File file; const File file;
ScopedPointer<InputStream> stream;
String storedPathname; String storedPathname;
int compressionLevel, compressedSize, headerStart;
Time fileTime;
int compressionLevel, compressedSize, uncompressedSize, headerStart;
unsigned long checksum; unsigned long checksum;
void writeTimeAndDate (OutputStream& target) const
static void writeTimeAndDate (OutputStream& target, Time t)
{ {
const Time t (file.getLastModificationTime());
target.writeShort ((short) (t.getSeconds() + (t.getMinutes() << 5) + (t.getHours() << 11))); target.writeShort ((short) (t.getSeconds() + (t.getMinutes() << 5) + (t.getHours() << 11)));
target.writeShort ((short) (t.getDayOfMonth() + ((t.getMonth() + 1) << 5) + ((t.getYear() - 1980) << 9))); target.writeShort ((short) (t.getDayOfMonth() + ((t.getMonth() + 1) << 5) + ((t.getYear() - 1980) << 9)));
} }
bool writeSource (OutputStream& target) bool writeSource (OutputStream& target)
{ {
checksum = 0;
FileInputStream input (file);
if (stream == nullptr)
{
stream = file.createInputStream();
if (input.failedToOpen())
return false;
if (stream == nullptr)
return false;
}
const int bufferSize = 2048;
checksum = 0;
uncompressedSize = 0;
const int bufferSize = 4096;
HeapBlock<unsigned char> buffer (bufferSize); HeapBlock<unsigned char> buffer (bufferSize);
while (! input.isExhausted())
while (! stream->isExhausted())
{ {
const int bytesRead = input.read (buffer, bufferSize);
const int bytesRead = stream->read (buffer, bufferSize);
if (bytesRead < 0) if (bytesRead < 0)
return false; return false;
checksum = juce_crc32 (checksum, buffer, (unsigned int) bytesRead);
checksum = zlibNamespace::crc32 (checksum, buffer, (unsigned int) bytesRead);
target.write (buffer, (size_t) bytesRead); target.write (buffer, (size_t) bytesRead);
uncompressedSize += bytesRead;
} }
stream = nullptr;
return true; return true;
} }
void writeFlagsAndSizes (OutputStream& target) const void writeFlagsAndSizes (OutputStream& target) const
{ {
target.writeShort (10); // version needed target.writeShort (10); // version needed
target.writeShort (0); // flags
target.writeShort ((short) (1 << 11)); // this flag indicates UTF-8 filename encoding
target.writeShort (compressionLevel > 0 ? (short) 8 : (short) 0); target.writeShort (compressionLevel > 0 ? (short) 8 : (short) 0);
writeTimeAndDate (target);
writeTimeAndDate (target, fileTime);
target.writeInt ((int) checksum); target.writeInt ((int) checksum);
target.writeInt (compressedSize); target.writeInt (compressedSize);
target.writeInt ((int) file.getSize());
target.writeInt (uncompressedSize);
target.writeShort ((short) storedPathname.toUTF8().sizeInBytes() - 1); target.writeShort ((short) storedPathname.toUTF8().sizeInBytes() - 1);
target.writeShort (0); // extra field length target.writeShort (0); // extra field length
} }
@@ -556,9 +558,18 @@ private:
ZipFile::Builder::Builder() {} ZipFile::Builder::Builder() {}
ZipFile::Builder::~Builder() {} ZipFile::Builder::~Builder() {}
void ZipFile::Builder::addFile (const File& fileToAdd, const int compressionLevel, const String& storedPathName)
void ZipFile::Builder::addFile (const File& file, const int compression, const String& path)
{
items.add (new Item (file, nullptr, compression,
path.isEmpty() ? file.getFileName() : path,
file.getLastModificationTime()));
}
void ZipFile::Builder::addEntry (InputStream* stream, int compression, const String& path, Time time)
{ {
items.add (new Item (fileToAdd, compressionLevel, storedPathName));
jassert (stream != nullptr); // must not be null!
jassert (path.isNotEmpty());
items.add (new Item (File(), stream, compression, path, time));
} }
bool ZipFile::Builder::writeToStream (OutputStream& target, double* const progress) const bool ZipFile::Builder::writeToStream (OutputStream& target, double* const progress) const


+ 15
- 0
source/modules/juce_core/zip/juce_ZipFile.h View File

@@ -196,6 +196,21 @@ public:
void addFile (const File& fileToAdd, int compressionLevel, void addFile (const File& fileToAdd, int compressionLevel,
const String& storedPathName = String::empty); const String& storedPathName = String::empty);
/** Adds a file while should be added to the archive.
@param streamToRead this stream isn't read immediately - a pointer to the stream is
stored, then used later when the writeToStream() method is called, and
deleted by the Builder object when no longer needed, so be very careful
about its lifetime and the lifetime of any objects on which it depends!
This must not be null.
@param compressionLevel this can be between 0 (no compression), and 9 (maximum compression).
@param storedPathName the partial pathname that will be stored for this file
@param fileModificationTime the timestamp that will be stored as the last modification time
of this entry
*/
void addEntry (InputStream* streamToRead, int compressionLevel,
const String& storedPathName, Time fileModificationTime);
/** Generates the zip file, writing it to the specified stream. /** Generates the zip file, writing it to the specified stream.
If the progress parameter is non-null, it will be updated with an approximate If the progress parameter is non-null, it will be updated with an approximate
progress status between 0 and 1.0 progress status between 0 and 1.0


+ 8
- 8
source/modules/juce_core/zip/zlib/crc32.c View File

@@ -251,8 +251,8 @@ unsigned long ZEXPORT crc32 (unsigned long crc, const unsigned char FAR *buf, un
/* ========================================================================= */ /* ========================================================================= */
#define DOLIT4 c ^= *buf4++; \ #define DOLIT4 c ^= *buf4++; \
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
c = (u4) (crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24])
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
/* ========================================================================= */ /* ========================================================================= */
@@ -264,7 +264,7 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf
c = (u4)crc; c = (u4)crc;
c = ~c; c = ~c;
while (len && ((ptrdiff_t)buf & 3)) { while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
c = (u4) (crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8));
len--; len--;
} }
@@ -280,7 +280,7 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf
buf = (const unsigned char FAR *)buf4; buf = (const unsigned char FAR *)buf4;
if (len) do { if (len) do {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
c = (u4) (crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8));
} while (--len); } while (--len);
c = ~c; c = ~c;
return (unsigned long)c; return (unsigned long)c;
@@ -288,8 +288,8 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf
/* ========================================================================= */ /* ========================================================================= */
#define DOBIG4 c ^= *++buf4; \ #define DOBIG4 c ^= *++buf4; \
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
c = (u4) (crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24])
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
/* ========================================================================= */ /* ========================================================================= */
@@ -301,7 +301,7 @@ local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf,
c = REV((u4)crc); c = REV((u4)crc);
c = ~c; c = ~c;
while (len && ((ptrdiff_t)buf & 3)) { while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
c = (u4) (crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8));
len--; len--;
} }
@@ -319,7 +319,7 @@ local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf,
buf = (const unsigned char FAR *)buf4; buf = (const unsigned char FAR *)buf4;
if (len) do { if (len) do {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
c = (u4) (crc_table[4][(c >> 24) ^ (u4) *buf++] ^ (c << 8));
} while (--len); } while (--len);
c = ~c; c = ~c;
return (unsigned long)(REV(c)); return (unsigned long)(REV(c));


+ 1
- 1
source/modules/juce_core/zip/zlib/inflate.c View File

@@ -131,7 +131,7 @@ int ZEXPORT inflatePrime (z_streamp strm, int bits, int value)
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
value &= (1L << bits) - 1;
value &= (1 << bits) - 1;
state->hold += value << state->bits; state->hold += value << state->bits;
state->bits += bits; state->bits += bits;
return Z_OK; return Z_OK;


+ 1
- 1
source/modules/juce_core/zip/zlib/trees.c View File

@@ -203,7 +203,7 @@ local void send_bits (deflate_state *s, int value, int length)
s->bi_buf |= (value << s->bi_valid); s->bi_buf |= (value << s->bi_valid);
put_short(s, s->bi_buf); put_short(s, s->bi_buf);
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
s->bi_valid += length - Buf_size;
s->bi_valid += (int) (length - Buf_size);
} else { } else {
s->bi_buf |= value << s->bi_valid; s->bi_buf |= value << s->bi_valid;
s->bi_valid += length; s->bi_valid += length;


Loading…
Cancel
Save