| @@ -1,9 +1,12 @@ | |||
| #!/bin/bash | |||
| set -e | |||
| JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/DISTRHO/libs/juce/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 | |||
| echo $M; | |||
| @@ -40,7 +40,7 @@ | |||
| do so, the class must fulfil these requirements: | |||
| - 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 | |||
| 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 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 | |||
| { | |||
| const ScopedLockType lock (getLock()); | |||
| deleteAllElements(); | |||
| data = static_cast<ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&&> (other.data); | |||
| numUsed = other.numUsed; | |||
| other.numUsed = 0; | |||
| @@ -30,6 +30,11 @@ DynamicObject::DynamicObject() | |||
| { | |||
| } | |||
| DynamicObject::DynamicObject (const DynamicObject& other) | |||
| : properties (other.properties) | |||
| { | |||
| } | |||
| DynamicObject::~DynamicObject() | |||
| { | |||
| } | |||
| @@ -78,12 +83,9 @@ void DynamicObject::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()) | |||
| { | |||
| @@ -93,8 +95,13 @@ DynamicObject::Ptr DynamicObject::clone() | |||
| else | |||
| 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) | |||
| @@ -46,9 +46,8 @@ class JUCE_API DynamicObject : public ReferenceCountedObject | |||
| public: | |||
| //============================================================================== | |||
| DynamicObject(); | |||
| /** Destructor. */ | |||
| virtual ~DynamicObject(); | |||
| DynamicObject (const DynamicObject&); | |||
| ~DynamicObject(); | |||
| typedef ReferenceCountedObjectPtr<DynamicObject> Ptr; | |||
| @@ -104,6 +103,9 @@ public: | |||
| /** Returns the NamedValueSet that holds the object's 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. | |||
| The default implementation of this method just returns a new DynamicObject | |||
| @@ -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) | |||
| { | |||
| } | |||
| @@ -49,22 +49,22 @@ NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (const NamedValu | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| 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 | |||
| { | |||
| 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; | |||
| } | |||
| #endif | |||
| @@ -268,7 +268,7 @@ void NamedValueSet::setFromXmlAttributes (const XmlElement& xml) | |||
| 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); | |||
| if (name.startsWith ("base64:")) | |||
| @@ -43,21 +43,21 @@ public: | |||
| NamedValueSet() noexcept; | |||
| /** Creates a copy of another set. */ | |||
| NamedValueSet (const NamedValueSet& other); | |||
| NamedValueSet (const NamedValueSet&); | |||
| /** Replaces this set with a copy of another set. */ | |||
| NamedValueSet& operator= (const NamedValueSet& other); | |||
| NamedValueSet& operator= (const NamedValueSet&); | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| NamedValueSet (NamedValueSet&& other) noexcept; | |||
| NamedValueSet& operator= (NamedValueSet&& other) noexcept; | |||
| NamedValueSet (NamedValueSet&&) noexcept; | |||
| NamedValueSet& operator= (NamedValueSet&&) noexcept; | |||
| #endif | |||
| /** Destructor. */ | |||
| ~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. */ | |||
| @@ -135,14 +135,14 @@ private: | |||
| public: | |||
| NamedValue() noexcept; | |||
| NamedValue (const NamedValue&); | |||
| NamedValue (const Identifier name, const var& value); | |||
| NamedValue (Identifier, const var&); | |||
| NamedValue& operator= (const NamedValue&); | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| NamedValue (NamedValue&&) noexcept; | |||
| NamedValue (const Identifier name, var&& value); | |||
| NamedValue (Identifier, var&&); | |||
| NamedValue& operator= (NamedValue&&) noexcept; | |||
| #endif | |||
| bool operator== (const NamedValue& other) const noexcept; | |||
| bool operator== (const NamedValue&) const noexcept; | |||
| LinkedListPointer<NamedValue> nextListItem; | |||
| Identifier name; | |||
| @@ -231,7 +231,7 @@ public: | |||
| @param objectToLookFor the object to look for | |||
| @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()); | |||
| ObjectClass* const* e = data.elements.getData(); | |||
| @@ -249,7 +249,7 @@ public: | |||
| @param objectToLookFor the object to look for | |||
| @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()); | |||
| 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, | |||
| 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 | |||
| */ | |||
| ObjectClass* add (ObjectClass* const newObject) noexcept | |||
| ObjectClass* add (ObjectClass* newObject) noexcept | |||
| { | |||
| const ScopedLockType lock (getLock()); | |||
| data.ensureAllocatedSize (numUsed + 1); | |||
| 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. | |||
| @@ -298,34 +299,31 @@ public: | |||
| @param indexToInsertAt the index at which the new element should be inserted | |||
| @param newObject the new object to add to the array | |||
| @returns the new object that was added | |||
| @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. | |||
| @@ -374,13 +372,16 @@ public: | |||
| If the array already contains a matching object, nothing will be done. | |||
| @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()); | |||
| if (! contains (newObject)) | |||
| add (newObject); | |||
| return newObject; | |||
| } | |||
| /** 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 | |||
| @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) | |||
| { | |||
| @@ -417,12 +416,12 @@ public: | |||
| toDelete.release(); | |||
| } | |||
| data.elements [indexToChange] = const_cast <ObjectClass*> (newObject); | |||
| data.elements [indexToChange] = newObject; | |||
| } | |||
| else | |||
| { | |||
| 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 | |||
| // 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. | |||
| @@ -504,10 +505,7 @@ public: | |||
| jassert (numElementsToAdd <= 0 || data.elements != nullptr); | |||
| 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. | |||
| @@ -581,8 +579,7 @@ public: | |||
| @param deleteObject whether to delete the object that is removed | |||
| @see removeObject, removeRange | |||
| */ | |||
| void remove (const int indexToRemove, | |||
| const bool deleteObject = true) | |||
| void remove (int indexToRemove, bool deleteObject = true) | |||
| { | |||
| ScopedPointer<ObjectClass> toDelete; | |||
| @@ -617,7 +614,7 @@ public: | |||
| @param indexToRemove the index of the element to remove | |||
| @see remove, removeObject, removeRange | |||
| */ | |||
| ObjectClass* removeAndReturn (const int indexToRemove) | |||
| ObjectClass* removeAndReturn (int indexToRemove) | |||
| { | |||
| ObjectClass* removedItem = nullptr; | |||
| const ScopedLockType lock (getLock()); | |||
| @@ -648,8 +645,7 @@ public: | |||
| @param deleteObject whether to delete the object (if it's found) | |||
| @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()); | |||
| ObjectClass** const e = data.elements.getData(); | |||
| @@ -677,9 +673,7 @@ public: | |||
| @param deleteObjects whether to delete the objects that get removed | |||
| @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 int endIndex = jlimit (0, numUsed, startIndex + numberToRemove); | |||
| @@ -719,7 +713,7 @@ public: | |||
| @see remove, removeObject, removeRange | |||
| */ | |||
| void removeLast (int howManyToRemove = 1, | |||
| const bool deleteObjects = true) | |||
| bool deleteObjects = true) | |||
| { | |||
| const ScopedLockType lock (getLock()); | |||
| @@ -734,8 +728,8 @@ public: | |||
| If either of the indexes passed in is out-of-range, nothing will happen, | |||
| 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()); | |||
| @@ -760,8 +754,7 @@ public: | |||
| @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 | |||
| */ | |||
| void move (const int currentIndex, | |||
| int newIndex) noexcept | |||
| void move (int currentIndex, int newIndex) noexcept | |||
| { | |||
| if (currentIndex != newIndex) | |||
| { | |||
| @@ -859,7 +852,7 @@ public: | |||
| */ | |||
| template <class ElementComparator> | |||
| 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 | |||
| // avoids getting warning messages about the parameter being unused | |||
| @@ -155,8 +155,8 @@ void PropertySet::removeValue (StringRef keyName) | |||
| 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 | |||
| @@ -69,7 +69,7 @@ public: | |||
| @param keyName the name of the property to retrieve | |||
| @param defaultReturnValue a value to return if the named property doesn't actually exist | |||
| */ | |||
| String getValue (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. | |||
| @@ -109,8 +109,8 @@ public: | |||
| /** 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 | |||
| property set (if you've specified one with the setFallbackPropertySet() method), | |||
| @@ -120,6 +120,9 @@ public: | |||
| 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; | |||
| } | |||
| @@ -147,6 +150,9 @@ public: | |||
| 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; | |||
| } | |||
| @@ -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 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 | |||
| { | |||
| @@ -75,7 +75,7 @@ const File File::nonexistent; | |||
| String File::parseAbsolutePath (const String& p) | |||
| { | |||
| if (p.isEmpty()) | |||
| return String::empty; | |||
| return String(); | |||
| #if JUCE_WINDOWS | |||
| // Windows.. | |||
| @@ -322,7 +322,7 @@ String File::getFileNameWithoutExtension() const | |||
| bool File::isAChildOf (const File& potentialParent) const | |||
| { | |||
| if (potentialParent == File::nonexistent) | |||
| if (potentialParent.fullPath.isEmpty()) | |||
| return false; | |||
| const String ourPath (getPathUpToLastSlash()); | |||
| @@ -482,11 +482,11 @@ bool File::loadFileAsData (MemoryBlock& destBlock) const | |||
| String File::loadFileAsString() const | |||
| { | |||
| if (! existsAsFile()) | |||
| return String::empty; | |||
| return String(); | |||
| FileInputStream in (*this); | |||
| return in.openedOk() ? in.readEntireStreamAsString() | |||
| : String::empty; | |||
| : String(); | |||
| } | |||
| void File::readLines (StringArray& destLines) const | |||
| @@ -598,7 +598,7 @@ String File::getFileExtension() const | |||
| if (indexOfDot > fullPath.lastIndexOfChar (separator)) | |||
| return fullPath.substring (indexOfDot); | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| bool File::hasFileExtension (StringRef possibleSuffix) const | |||
| @@ -629,7 +629,7 @@ bool File::hasFileExtension (StringRef possibleSuffix) const | |||
| File File::withFileExtension (StringRef newExtension) const | |||
| { | |||
| if (fullPath.isEmpty()) | |||
| return File::nonexistent; | |||
| return File(); | |||
| String filePart (getFileName()); | |||
| @@ -741,7 +741,7 @@ public: | |||
| @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. | |||
| @see startAsProcess | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| @@ -101,7 +101,7 @@ public: | |||
| /** Merges another search path into this one. | |||
| 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. | |||
| @@ -50,7 +50,7 @@ TemporaryFile::TemporaryFile (const File& target, const int optionFlags) | |||
| targetFile (target) | |||
| { | |||
| // 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) | |||
| @@ -79,7 +79,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const | |||
| { | |||
| // This method only works if you created this object with the constructor | |||
| // that takes a target file! | |||
| jassert (targetFile != File::nonexistent); | |||
| jassert (targetFile != File()); | |||
| if (temporaryFile.exists()) | |||
| { | |||
| @@ -89,7 +89,7 @@ public: | |||
| The file will not be created until you write to it. And remember that when | |||
| this object is deleted, the file will also be deleted! | |||
| */ | |||
| TemporaryFile (const String& suffix = String::empty, | |||
| TemporaryFile (const String& suffix = String(), | |||
| int optionFlags = 0); | |||
| /** Creates a temporary file in the same directory as a specified 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; | |||
| } | |||
| @@ -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 | |||
| @@ -35,7 +35,7 @@ public: | |||
| 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 parseArray (t, result); | |||
| } | |||
| @@ -100,7 +100,6 @@ public: | |||
| return Result::ok(); | |||
| } | |||
| private: | |||
| static Result parseAny (String::CharPointerType& t, var& result) | |||
| { | |||
| t = t.findEndOfWhitespace(); | |||
| @@ -148,7 +147,7 @@ private: | |||
| if (t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'l' && t2.getAndAdvance() == 'l') | |||
| { | |||
| t = t2; | |||
| result = var::null; | |||
| result = var(); | |||
| return Result::ok(); | |||
| } | |||
| break; | |||
| @@ -160,6 +159,7 @@ private: | |||
| return createFail ("Syntax error", &t); | |||
| } | |||
| private: | |||
| static Result createFail (const char* const message, const String::CharPointerType* location = nullptr) | |||
| { | |||
| String m (message); | |||
| @@ -254,7 +254,7 @@ private: | |||
| if (c2 != ':') | |||
| return createFail ("Expected ':', but found", &oldT); | |||
| resultProperties.set (propertyName, var::null); | |||
| resultProperties.set (propertyName, var()); | |||
| var* propertyValue = resultProperties.getVarPointer (propertyName); | |||
| Result r2 (parseAny (t, *propertyValue)); | |||
| @@ -300,7 +300,7 @@ private: | |||
| return createFail ("Unexpected end-of-input in array declaration"); | |||
| t = oldT; | |||
| destArray->add (var::null); | |||
| destArray->add (var()); | |||
| Result r (parseAny (t, destArray->getReference (destArray->size() - 1))); | |||
| if (r.failed()) | |||
| @@ -460,51 +460,6 @@ public: | |||
| 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 }; | |||
| }; | |||
| @@ -513,8 +468,18 @@ var JSON::parse (const String& text) | |||
| { | |||
| 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; | |||
| } | |||
| @@ -610,7 +575,7 @@ public: | |||
| { | |||
| switch (r.nextInt (depth > 3 ? 6 : 8)) | |||
| { | |||
| case 0: return var::null; | |||
| case 0: return var(); | |||
| case 1: return r.nextInt(); | |||
| case 2: return r.nextInt64(); | |||
| case 3: return r.nextBool(); | |||
| @@ -638,7 +603,7 @@ public: | |||
| } | |||
| default: | |||
| return var::null; | |||
| return var(); | |||
| } | |||
| } | |||
| @@ -53,6 +53,10 @@ public: | |||
| 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. | |||
| 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); | |||
| @@ -60,6 +64,10 @@ public: | |||
| 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. | |||
| 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); | |||
| @@ -94,6 +102,13 @@ public: | |||
| static String toString (const var& objectToFormat, | |||
| 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. | |||
| 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. | |||
| @@ -106,7 +121,7 @@ public: | |||
| /** Returns a version of a string with any extended characters escaped. */ | |||
| 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. | |||
| This advances the text parameter, leaving it positioned after the closing quote. | |||
| */ | |||
| @@ -90,15 +90,6 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| 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) | |||
| { | |||
| @@ -191,6 +182,32 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| : 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 | |||
| { | |||
| if (Time::getCurrentTime() > root->timeout) | |||
| @@ -281,11 +298,10 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| if (r == returnWasHit) return r; | |||
| if (r == breakWasHit) break; | |||
| if (r == continueWasHit) continue; | |||
| iterator->perform (s, nullptr); | |||
| if (isDoLoop && ! condition->getResult (s)) | |||
| if (isDoLoop && r != continueWasHit && ! condition->getResult (s)) | |||
| break; | |||
| } | |||
| @@ -656,14 +672,13 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| var getResult (const Scope& s) const override | |||
| { | |||
| var function (object->getResult (s)); | |||
| if (DotOperator* dot = dynamic_cast<DotOperator*> (object.get())) | |||
| { | |||
| var thisObject (dot->parent->getResult (s)); | |||
| return invokeFunction (s, s.findFunctionCall (location, thisObject, dot->child), thisObject); | |||
| } | |||
| var function (object->getResult (s)); | |||
| 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 | |||
| { | |||
| out << "function" << functionCode; | |||
| out << "function " << functionCode; | |||
| } | |||
| var invoke (const Scope& s, const var::NativeFunctionArgs& args) const | |||
| @@ -773,9 +788,9 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| static const Identifier thisIdent ("this"); | |||
| 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; | |||
| 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::true_)) return parseSuffixes (new LiteralValue (location, (int) 1)); | |||
| 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 (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 returnVal (var::undefined()); | |||
| try | |||
| { | |||
| prepareTimeout(); | |||
| if (result != nullptr) *result = Result::ok(); | |||
| return root->invoke (function, args); | |||
| RootObject::Scope (nullptr, root, root).findAndInvokeMethod (function, args, returnVal); | |||
| } | |||
| catch (String& error) | |||
| { | |||
| if (result != nullptr) *result = Result::fail (error); | |||
| } | |||
| return var::undefined(); | |||
| return returnVal; | |||
| } | |||
| #if JUCE_MSVC | |||
| @@ -26,7 +26,6 @@ | |||
| ============================================================================== | |||
| */ | |||
| /** | |||
| A simple javascript interpreter! | |||
| @@ -98,7 +97,7 @@ public: | |||
| RelativeTime maximumExecutionTime; | |||
| private: | |||
| struct RootObject; | |||
| JUCE_PUBLIC_IN_DLL_BUILD (struct RootObject) | |||
| ReferenceCountedObjectPtr<RootObject> root; | |||
| void prepareTimeout() const; | |||
| @@ -165,6 +165,8 @@ namespace juce | |||
| #include "zip/juce_GZIPDecompressorInputStream.cpp" | |||
| #include "zip/juce_GZIPCompressorOutputStream.cpp" | |||
| #include "zip/juce_ZipFile.cpp" | |||
| #include "files/juce_FileFilter.cpp" | |||
| #include "files/juce_WildcardFileFilter.cpp" | |||
| //============================================================================== | |||
| #if JUCE_MAC || JUCE_IOS | |||
| @@ -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_MemoryMappedFile.h" | |||
| #include "files/juce_TemporaryFile.h" | |||
| #include "files/juce_FileFilter.h" | |||
| #include "files/juce_WildcardFileFilter.h" | |||
| #include "streams/juce_FileInputSource.h" | |||
| #include "logging/juce_FileLogger.h" | |||
| #include "javascript/juce_JSON.h" | |||
| @@ -951,7 +951,7 @@ String BigInteger::toString (const int base, const int minimumNumCharacters) con | |||
| else | |||
| { | |||
| jassertfalse; // can't do the specified base! | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| s = s.paddedLeft ('0', minimumNumCharacters); | |||
| @@ -65,11 +65,11 @@ public: | |||
| BigInteger (int64 value); | |||
| /** Creates a copy of another BigInteger. */ | |||
| BigInteger (const BigInteger& other); | |||
| BigInteger (const BigInteger&); | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| BigInteger (BigInteger&& other) noexcept; | |||
| BigInteger& operator= (BigInteger&& other) noexcept; | |||
| BigInteger (BigInteger&&) noexcept; | |||
| BigInteger& operator= (BigInteger&&) noexcept; | |||
| #endif | |||
| /** Destructor. */ | |||
| @@ -77,10 +77,10 @@ public: | |||
| //============================================================================== | |||
| /** Copies another BigInteger onto this one. */ | |||
| BigInteger& operator= (const BigInteger& other); | |||
| BigInteger& operator= (const BigInteger&); | |||
| /** 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. | |||
| @@ -183,14 +183,14 @@ public: | |||
| //============================================================================== | |||
| // 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++(); | |||
| @@ -199,23 +199,23 @@ public: | |||
| BigInteger operator-- (int); | |||
| 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; | |||
| 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. | |||
| @@ -243,8 +243,7 @@ public: | |||
| */ | |||
| 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; | |||
| /** Performs a combined exponent and modulo operation. | |||
| @@ -310,12 +309,12 @@ public: | |||
| private: | |||
| //============================================================================== | |||
| HeapBlock <uint32> values; | |||
| HeapBlock<uint32> values; | |||
| size_t numValues; | |||
| int highestBit; | |||
| bool negative; | |||
| void ensureSize (size_t numVals); | |||
| void ensureSize (size_t); | |||
| void shiftLeft (int bits, int startBit); | |||
| void shiftRight (int bits, int startBit); | |||
| @@ -53,7 +53,7 @@ public: | |||
| virtual String getName() const | |||
| { | |||
| 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) | |||
| @@ -188,12 +188,10 @@ struct Expression::Helpers | |||
| if (input != left && input != right) | |||
| 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 | |||
| { | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| @@ -59,14 +59,14 @@ public: | |||
| explicit Expression (double constant); | |||
| /** Creates a copy of an expression. */ | |||
| Expression (const Expression& other); | |||
| Expression (const Expression&); | |||
| /** Copies another expression. */ | |||
| Expression& operator= (const Expression& other); | |||
| Expression& operator= (const Expression&); | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| Expression (Expression&& other) noexcept; | |||
| Expression& operator= (Expression&& other) noexcept; | |||
| Expression (Expression&&) noexcept; | |||
| Expression& operator= (Expression&&) noexcept; | |||
| #endif | |||
| /** Creates an expression by parsing a string. | |||
| @@ -78,14 +78,14 @@ public: | |||
| /** Returns a string version of the expression. */ | |||
| 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. */ | |||
| Expression operator- (const Expression& other) const; | |||
| Expression operator- (const Expression&) const; | |||
| /** 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. */ | |||
| Expression operator/ (const Expression& other) const; | |||
| Expression operator/ (const Expression&) const; | |||
| /** Returns an expression which performs a negation operation on an existing expression. */ | |||
| Expression operator-() const; | |||
| @@ -187,8 +187,8 @@ private: | |||
| /* | |||
| 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 | |||
| #define JUCE_MAC_ATOMICS_VOLATILE | |||
| @@ -196,7 +196,7 @@ private: | |||
| #define JUCE_MAC_ATOMICS_VOLATILE volatile | |||
| #endif | |||
| #if JUCE_PPC || JUCE_IOS | |||
| #if JUCE_PPC | |||
| // 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 OSAtomicIncrement64Barrier (JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return ++*a; } | |||
| @@ -207,7 +207,7 @@ private: | |||
| #endif | |||
| //============================================================================== | |||
| #elif JUCE_GCC | |||
| #elif JUCE_GCC || JUCE_CLANG | |||
| #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) | |||
| @@ -258,6 +258,7 @@ private: | |||
| #endif | |||
| #endif | |||
| #if JUCE_MSVC | |||
| #pragma warning (push) | |||
| #pragma warning (disable: 4311) // (truncation warning) | |||
| @@ -267,7 +268,7 @@ private: | |||
| template <typename Type> | |||
| 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)) | |||
| : castFrom64Bit ((int64) OSAtomicAdd64Barrier ((int64_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value)); | |||
| #elif JUCE_ATOMICS_WINDOWS | |||
| @@ -282,7 +283,7 @@ inline Type Atomic<Type>::get() const noexcept | |||
| template <typename Type> | |||
| 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; | |||
| while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; } | |||
| return currentVal; | |||
| @@ -295,7 +296,7 @@ inline Type Atomic<Type>::exchange (const Type newValue) noexcept | |||
| template <typename Type> | |||
| 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) | |||
| : (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); | |||
| #elif JUCE_ATOMICS_WINDOWS | |||
| @@ -315,35 +316,37 @@ inline Type Atomic<Type>::operator-= (const Type amountToSubtract) noexcept | |||
| template <typename Type> | |||
| 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) | |||
| : (Type) OSAtomicIncrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); | |||
| #elif JUCE_ATOMICS_WINDOWS | |||
| return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) | |||
| : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); | |||
| #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 | |||
| } | |||
| template <typename Type> | |||
| 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) | |||
| : (Type) OSAtomicDecrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); | |||
| #elif JUCE_ATOMICS_WINDOWS | |||
| return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) | |||
| : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); | |||
| #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 | |||
| } | |||
| template <typename Type> | |||
| 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) | |||
| : OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); | |||
| #elif JUCE_ATOMICS_WINDOWS | |||
| @@ -357,7 +360,7 @@ inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type val | |||
| template <typename Type> | |||
| 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.. | |||
| { | |||
| if (compareAndSetBool (newValue, valueToCompare)) | |||
| @@ -380,7 +383,7 @@ inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type va | |||
| template <typename Type> | |||
| inline void Atomic<Type>::memoryBarrier() noexcept | |||
| { | |||
| #if JUCE_ATOMICS_MAC | |||
| #if JUCE_ATOMICS_MAC_LEGACY | |||
| OSMemoryBarrier(); | |||
| #elif JUCE_ATOMICS_GCC | |||
| __sync_synchronize(); | |||
| @@ -26,7 +26,6 @@ | |||
| ============================================================================== | |||
| */ | |||
| Uuid::Uuid() | |||
| { | |||
| Random r; | |||
| @@ -80,7 +80,7 @@ File File::getSpecialLocation (const SpecialLocationType type) | |||
| break; | |||
| } | |||
| return File::nonexistent; | |||
| return File(); | |||
| } | |||
| bool File::moveToTrash() const | |||
| @@ -87,6 +87,10 @@ public: | |||
| 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, | |||
| JuceAppActivity.createHTTPStream, | |||
| javaString (address).get(), | |||
| @@ -192,6 +192,11 @@ String SystemStats::getOperatingSystemName() | |||
| return "Android " + AndroidStatsHelpers::getSystemProperty ("os.version"); | |||
| } | |||
| String SystemStats::getDeviceDescription() | |||
| { | |||
| return String::empty; | |||
| } | |||
| bool SystemStats::isOperatingSystem64Bit() | |||
| { | |||
| #if JUCE_64BIT | |||
| @@ -72,7 +72,7 @@ bool File::isOnRemovableDrive() 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())) | |||
| return File (CharPointer_UTF8 (pw->pw_dir)); | |||
| return File::nonexistent; | |||
| return File(); | |||
| } | |||
| case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~"); | |||
| @@ -163,7 +163,7 @@ File File::getSpecialLocation (const SpecialLocationType type) | |||
| break; | |||
| } | |||
| return File::nonexistent; | |||
| return File(); | |||
| } | |||
| //============================================================================== | |||
| @@ -309,7 +309,7 @@ private: | |||
| { | |||
| char c = 0; | |||
| if (read (&c, 1) != 1) | |||
| return String::empty; | |||
| return String(); | |||
| buffer.writeByte (c); | |||
| @@ -324,7 +324,7 @@ private: | |||
| if (header.startsWithIgnoreCase ("HTTP/")) | |||
| return header; | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| static void writeValueIfNotPresent (MemoryOutputStream& dest, const String& headers, const String& key, const String& value) | |||
| @@ -432,7 +432,7 @@ private: | |||
| if (lines[i].startsWithIgnoreCase (itemName)) | |||
| return lines[i].substring (itemName.length()).trim(); | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) | |||
| @@ -42,6 +42,11 @@ String SystemStats::getOperatingSystemName() | |||
| return "Linux"; | |||
| } | |||
| String SystemStats::getDeviceDescription() | |||
| { | |||
| return String(); | |||
| } | |||
| bool SystemStats::isOperatingSystem64Bit() | |||
| { | |||
| #if JUCE_64BIT | |||
| @@ -64,7 +69,7 @@ namespace LinuxStatsHelpers | |||
| if (lines[i].startsWithIgnoreCase (key)) | |||
| 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())) | |||
| return CharPointer_UTF8 (pw->pw_name); | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| String SystemStats::getFullUserName() | |||
| @@ -116,7 +121,7 @@ String SystemStats::getComputerName() | |||
| if (gethostname (name, sizeof (name) - 1) == 0) | |||
| return name; | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| static String getLocaleValue (nl_item key) | |||
| @@ -257,7 +257,7 @@ File File::getSpecialLocation (const SpecialLocationType type) | |||
| return File (resultPath.convertToPrecomposedUnicode()); | |||
| } | |||
| return File::nonexistent; | |||
| return File(); | |||
| } | |||
| //============================================================================== | |||
| @@ -271,7 +271,7 @@ String File::getVersion() const | |||
| return nsStringToJuce (name); | |||
| } | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| //============================================================================== | |||
| @@ -356,7 +356,7 @@ public: | |||
| return false; | |||
| [enumerator skipDescendents]; | |||
| filenameFound = nsStringToJuce (file); | |||
| filenameFound = nsStringToJuce (file).convertToPrecomposedUnicode(); | |||
| if (wildcardUTF8 == nullptr) | |||
| wildcardUTF8 = wildCard.toUTF8(); | |||
| @@ -29,7 +29,7 @@ | |||
| String String::fromCFString (CFStringRef cfString) | |||
| { | |||
| if (cfString == 0) | |||
| return String::empty; | |||
| return String(); | |||
| CFRange range = { 0, CFStringGetLength (cfString) }; | |||
| HeapBlock <UniChar> u ((size_t) range.length + 1); | |||
| @@ -124,7 +124,7 @@ SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() | |||
| return iOS; | |||
| #else | |||
| StringArray parts; | |||
| parts.addTokens (getOSXVersion(), ".", String::empty); | |||
| parts.addTokens (getOSXVersion(), ".", String()); | |||
| jassert (parts[0].getIntValue() == 10); | |||
| const int major = parts[1].getIntValue(); | |||
| @@ -143,6 +143,15 @@ String SystemStats::getOperatingSystemName() | |||
| #endif | |||
| } | |||
| String SystemStats::getDeviceDescription() | |||
| { | |||
| #if JUCE_IOS | |||
| return nsStringToJuce ([[UIDevice currentDevice] model]); | |||
| #else | |||
| return String(); | |||
| #endif | |||
| } | |||
| bool SystemStats::isOperatingSystem64Bit() | |||
| { | |||
| #if JUCE_IOS | |||
| @@ -173,7 +182,7 @@ String SystemStats::getCpuVendor() | |||
| return String (reinterpret_cast <const char*> (vendor), 12); | |||
| #else | |||
| return String::empty; | |||
| return String(); | |||
| #endif | |||
| } | |||
| @@ -209,7 +218,7 @@ String SystemStats::getComputerName() | |||
| if (gethostname (name, sizeof (name) - 1) == 0) | |||
| return String (name).upToLastOccurrenceOf (".local", false, true); | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| static String getLocaleValue (CFStringRef key) | |||
| @@ -194,7 +194,12 @@ bool NamedPipe::openInternal (const String& pipeName, const bool createPipe) | |||
| pimpl = new Pimpl (File::getSpecialLocation (File::tempDirectory) | |||
| .getChildFile (File::createLegalFileName (pipeName)).getFullPathName(), createPipe); | |||
| #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 | |||
| if (createPipe && ! pimpl->createFifos()) | |||
| @@ -636,7 +636,7 @@ String File::getVolumeLabel() const | |||
| } | |||
| #endif | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| int File::getVolumeSerialNumber() const | |||
| @@ -93,7 +93,7 @@ namespace WindowsFileHelpers | |||
| if (SHGetSpecialFolderPath (0, path, type, FALSE)) | |||
| return File (String (path)); | |||
| return File::nonexistent; | |||
| return File(); | |||
| } | |||
| File getModuleFileName (HINSTANCE moduleHandle) | |||
| @@ -542,7 +542,7 @@ File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) | |||
| default: | |||
| jassertfalse; // unknown type? | |||
| return File::nonexistent; | |||
| return File(); | |||
| } | |||
| return WindowsFileHelpers::getSpecialFolderPath (csidlType); | |||
| @@ -630,6 +630,8 @@ bool File::createLink (const String& description, const File& linkFileToCreate) | |||
| ComSmartPtr<IShellLink> shellLink; | |||
| ComSmartPtr<IPersistFile> persistFile; | |||
| CoInitialize (0); | |||
| return SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink)) | |||
| && SUCCEEDED (shellLink->SetPath (getFullPathName().toWideCharPointer())) | |||
| && SUCCEEDED (shellLink->SetDescription (description.toWideCharPointer())) | |||
| @@ -197,6 +197,11 @@ String SystemStats::getOperatingSystemName() | |||
| return name; | |||
| } | |||
| String SystemStats::getDeviceDescription() | |||
| { | |||
| return String::empty; | |||
| } | |||
| bool SystemStats::isOperatingSystem64Bit() | |||
| { | |||
| #if JUCE_64BIT | |||
| @@ -55,7 +55,7 @@ IPAddress::IPAddress (uint32 n) noexcept | |||
| IPAddress::IPAddress (const String& adr) | |||
| { | |||
| StringArray tokens; | |||
| tokens.addTokens (adr, ".", String::empty); | |||
| tokens.addTokens (adr, ".", String()); | |||
| for (int i = 0; i < 4; ++i) | |||
| address[i] = (uint8) tokens[i].getIntValue(); | |||
| @@ -51,10 +51,10 @@ public: | |||
| MACAddress(); | |||
| /** Creates a copy of another address. */ | |||
| MACAddress (const MACAddress& other); | |||
| MACAddress (const MACAddress&); | |||
| /** Creates a copy of another address. */ | |||
| MACAddress& operator= (const MACAddress& other); | |||
| MACAddress& operator= (const MACAddress&); | |||
| /** Creates an address from 6 bytes. */ | |||
| explicit MACAddress (const uint8 bytes[6]); | |||
| @@ -75,8 +75,8 @@ public: | |||
| /** Returns true if this address is null (00-00-00-00-00-00). */ | |||
| 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: | |||
| @@ -386,7 +386,7 @@ void StreamingSocket::close() | |||
| ::close (handle); | |||
| #endif | |||
| hostName = String::empty; | |||
| hostName.clear(); | |||
| portNumber = 0; | |||
| handle = -1; | |||
| isListener = false; | |||
| @@ -506,7 +506,7 @@ void DatagramSocket::close() | |||
| ::close (handle); | |||
| #endif | |||
| hostName = String::empty; | |||
| hostName.clear(); | |||
| portNumber = 0; | |||
| handle = -1; | |||
| } | |||
| @@ -146,7 +146,7 @@ public: | |||
| @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 | |||
| socket. | |||
| @@ -181,7 +181,7 @@ namespace URLHelpers | |||
| << "\"; filename=\"" << file.getFileName() << "\"\r\n"; | |||
| const String mimeType (url.getMimeTypesOfUploadFiles() | |||
| .getValue (paramName, String::empty)); | |||
| .getValue (paramName, String())); | |||
| if (mimeType.isNotEmpty()) | |||
| data << "Content-Type: " << mimeType << "\r\n"; | |||
| @@ -253,7 +253,7 @@ String URL::getSubPath() const | |||
| { | |||
| const int startOfPath = URLHelpers::findStartOfPath (url); | |||
| return startOfPath <= 0 ? String::empty | |||
| return startOfPath <= 0 ? String() | |||
| : url.substring (startOfPath); | |||
| } | |||
| @@ -363,7 +363,7 @@ String URL::readEntireTextStream (const bool usePostCommand) const | |||
| if (in != nullptr) | |||
| return in->readEntireStreamAsString(); | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const | |||
| @@ -470,5 +470,5 @@ bool URL::launchInDefaultBrowser() const | |||
| if (u.containsChar ('@') && ! u.containsChar (':')) | |||
| u = "mailto:" + u; | |||
| return Process::openDocument (u, String::empty); | |||
| return Process::openDocument (u, String()); | |||
| } | |||
| @@ -251,7 +251,7 @@ public: | |||
| InputStream* createInputStream (bool usePostCommand, | |||
| OpenStreamProgressCallback* progressCallback = nullptr, | |||
| void* progressCallbackContext = nullptr, | |||
| String extraHeaders = String::empty, | |||
| String extraHeaders = String(), | |||
| int connectionTimeOutMs = 0, | |||
| StringPairArray* responseHeaders = nullptr) const; | |||
| @@ -34,9 +34,9 @@ | |||
| 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. | |||
| @@ -83,8 +83,7 @@ public: | |||
| */ | |||
| 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(); | |||
| /** Returns an environment variable. | |||
| @@ -122,6 +121,12 @@ public: | |||
| */ | |||
| 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.. | |||
| @@ -441,7 +441,7 @@ public: | |||
| /** Returns true if this data contains a valid string in this encoding. */ | |||
| static bool isValidString (const CharType* dataToTest, int maxBytesToRead) | |||
| { | |||
| maxBytesToRead /= sizeof (CharType); | |||
| maxBytesToRead /= (int) sizeof (CharType); | |||
| while (--maxBytesToRead >= 0 && *dataToTest != 0) | |||
| { | |||
| @@ -355,7 +355,7 @@ public: | |||
| /** Returns true if this data contains a valid string in this encoding. */ | |||
| static bool isValidString (const CharType* dataToTest, int maxBytesToRead) | |||
| { | |||
| maxBytesToRead /= sizeof (CharType); | |||
| maxBytesToRead /= (int) sizeof (CharType); | |||
| while (--maxBytesToRead >= 0 && *dataToTest != 0) | |||
| if (! canRepresent (*dataToTest++)) | |||
| @@ -171,11 +171,12 @@ public: | |||
| while (--numExtraValues >= 0) | |||
| { | |||
| const uint32 nextByte = (uint32) (uint8) *data++; | |||
| const uint32 nextByte = (uint32) (uint8) *data; | |||
| if ((nextByte & 0xc0) != 0x80) | |||
| break; | |||
| ++data; | |||
| n <<= 6; | |||
| n |= (nextByte & 0x3f); | |||
| } | |||
| @@ -248,16 +249,8 @@ public: | |||
| if ((n & 0x80) != 0) | |||
| { | |||
| uint32 bit = 0x40; | |||
| while ((n & bit) != 0) | |||
| { | |||
| while ((*d & 0xc0) == 0x80) | |||
| ++d; | |||
| bit >>= 1; | |||
| if (bit == 0) | |||
| break; // illegal utf-8 sequence | |||
| } | |||
| } | |||
| else if (n == 0) | |||
| break; | |||
| @@ -594,8 +594,8 @@ public: | |||
| /** Returns a pointer to the first character in the string which is found in | |||
| 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; | |||
| @@ -36,6 +36,21 @@ LocalisedStrings::LocalisedStrings (const File& fileToLoad, bool 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() | |||
| { | |||
| } | |||
| @@ -43,11 +58,17 @@ LocalisedStrings::~LocalisedStrings() | |||
| //============================================================================== | |||
| String LocalisedStrings::translate (const String& text) const | |||
| { | |||
| if (fallback != nullptr && ! translations.containsKey (text)) | |||
| return fallback->translate (text); | |||
| return translations.getValue (text, text); | |||
| } | |||
| 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); | |||
| } | |||
| @@ -73,7 +94,7 @@ namespace | |||
| SpinLock currentMappingsLock; | |||
| ScopedPointer<LocalisedStrings> currentMappings; | |||
| int findCloseQuote (const String& text, int startPos) | |||
| static int findCloseQuote (const String& text, int startPos) | |||
| { | |||
| juce_wchar lastChar = 0; | |||
| String::CharPointerType t (text.getCharPointer() + startPos); | |||
| @@ -92,7 +113,7 @@ namespace | |||
| return startPos; | |||
| } | |||
| String unescapeString (const String& s) | |||
| static String unescapeString (const String& s) | |||
| { | |||
| return s.replace ("\\\"", "\"") | |||
| .replace ("\\\'", "\'") | |||
| @@ -141,6 +162,8 @@ void LocalisedStrings::loadFromText (const String& fileContents, bool ignoreCase | |||
| countryCodes.removeEmptyStrings(); | |||
| } | |||
| } | |||
| translations.minimiseStorageOverheads(); | |||
| } | |||
| void LocalisedStrings::addStrings (const LocalisedStrings& other) | |||
| @@ -151,6 +174,11 @@ void LocalisedStrings::addStrings (const LocalisedStrings& other) | |||
| translations.addArray (other.translations); | |||
| } | |||
| void LocalisedStrings::setFallback (LocalisedStrings* f) | |||
| { | |||
| fallback = f; | |||
| } | |||
| //============================================================================== | |||
| void LocalisedStrings::setCurrentMappings (LocalisedStrings* newTranslations) | |||
| { | |||
| @@ -82,16 +82,17 @@ public: | |||
| When you create one of these, you can call setCurrentMappings() to make it | |||
| 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. | |||
| When you create one of these, you can call setCurrentMappings() to make it | |||
| 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. */ | |||
| ~LocalisedStrings(); | |||
| @@ -100,7 +101,7 @@ public: | |||
| /** 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 | |||
| 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. | |||
| See also the TRANS() macro, which uses the current set to do its translation. | |||
| @@ -183,11 +184,19 @@ public: | |||
| */ | |||
| 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: | |||
| //============================================================================== | |||
| String languageName; | |||
| StringArray countryCodes; | |||
| StringPairArray translations; | |||
| ScopedPointer<LocalisedStrings> fallback; | |||
| friend struct ContainerDeletePolicy<LocalisedStrings>; | |||
| void loadFromText (const String&, bool ignoreCase); | |||
| @@ -259,6 +259,12 @@ void String::swapWith (String& other) noexcept | |||
| std::swap (text, other.text); | |||
| } | |||
| void String::clear() noexcept | |||
| { | |||
| StringHolder::release (text); | |||
| text = &(emptyString.text); | |||
| } | |||
| String& String::operator= (const String& other) noexcept | |||
| { | |||
| 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, | |||
| 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. | |||
| 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())); | |||
| } | |||
| @@ -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, | |||
| 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. | |||
| 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)); | |||
| } | |||
| @@ -419,7 +433,8 @@ namespace NumberToStringConverters | |||
| { | |||
| explicit StackArrayStream (char* d) | |||
| { | |||
| imbue (std::locale::classic()); | |||
| static const std::locale classicLocale (std::locale::classic()); | |||
| imbue (classicLocale); | |||
| setp (d, d + charsNeededForDouble); | |||
| } | |||
| @@ -684,23 +699,28 @@ String& String::operator+= (const juce_wchar ch) | |||
| String& String::operator+= (const int number) | |||
| { | |||
| 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; | |||
| } | |||
| @@ -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 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 uint64 number) { return s1 += String (number); } | |||
| 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 += "xyz"; | |||
| expect (s2 == "1234567890xyz"); | |||
| s2 += (int) 123; | |||
| expect (s2 == "1234567890xyz123"); | |||
| s2 += (int64) 123; | |||
| expect (s2 == "1234567890xyz123123"); | |||
| beginTest ("Numeric conversions"); | |||
| expect (String::empty.getIntValue() == 0); | |||
| @@ -2388,6 +2413,28 @@ public: | |||
| expectEquals (toks.size(), 3); | |||
| 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)); | |||
| } | |||
| } | |||
| }; | |||
| @@ -204,6 +204,8 @@ public: | |||
| String& operator+= (const wchar_t* textToAppend); | |||
| /** Appends a decimal number at the end of this string. */ | |||
| 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. */ | |||
| String& operator+= (char characterToAppend); | |||
| /** Appends a character at the end of this string. */ | |||
| @@ -228,6 +230,32 @@ public: | |||
| void appendCharPointer (const CharPointerType startOfTextToAppend, | |||
| 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. */ | |||
| void appendCharPointer (const CharPointerType textToAppend); | |||
| @@ -241,21 +269,18 @@ public: | |||
| { | |||
| 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()); | |||
| ++numChars; | |||
| } | |||
| if (numChars > 0) | |||
| if (extraBytesNeeded > 0) | |||
| { | |||
| const size_t byteOffsetOfNull = getByteOffsetOfEnd(); | |||
| 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> | |||
| 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; } | |||
| /** Resets this string to be empty. */ | |||
| void clear() noexcept; | |||
| /** Case-insensitive comparison with another string. */ | |||
| bool equalsIgnoreCase (const String& other) const noexcept; | |||
| @@ -1216,7 +1230,6 @@ private: | |||
| }; | |||
| explicit String (const PreallocationBytes&); // This constructor preallocates a certain amount of memory | |||
| void appendFixedLength (const char* text, int numExtraChars); | |||
| size_t getByteOffsetOfEnd() const noexcept; | |||
| 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. */ | |||
| JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int64 number); | |||
| /** 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); | |||
| /** Appends a decimal number at the end of a string. */ | |||
| JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, double number); | |||
| @@ -293,7 +293,7 @@ String StringArray::joinIntoString (StringRef separator, int start, int numberTo | |||
| start = 0; | |||
| if (start >= last) | |||
| return String::empty; | |||
| return String(); | |||
| if (start == last - 1) | |||
| return strings.getReference (start); | |||
| @@ -189,7 +189,6 @@ public: | |||
| void insert (int index, const String& stringToAdd); | |||
| /** Adds a string to the array as long as it's not already in there. | |||
| The search can optionally be case-insensitive. | |||
| */ | |||
| void addIfNotAlreadyThere (const String& stringToAdd, bool ignoreCase = false); | |||
| @@ -325,7 +324,6 @@ public: | |||
| void removeDuplicates (bool ignoreCase); | |||
| /** Removes empty strings from the array. | |||
| @param removeWhitespaceStrings if true, strings that only contain whitespace | |||
| characters will also be removed | |||
| */ | |||
| @@ -411,11 +409,12 @@ public: | |||
| */ | |||
| 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; | |||
| private: | |||
| JUCE_LEAK_DETECTOR (StringArray) | |||
| }; | |||
| @@ -78,6 +78,11 @@ String StringPairArray::getValue (StringRef key, const String& defaultReturnValu | |||
| return defaultReturnValue; | |||
| } | |||
| bool StringPairArray::containsKey (StringRef key) const noexcept | |||
| { | |||
| return keys.contains (key); | |||
| } | |||
| void StringPairArray::set (const String& key, const String& value) | |||
| { | |||
| const int i = keys.indexOf (key, ignoreCase); | |||
| @@ -85,6 +85,8 @@ public: | |||
| */ | |||
| 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. */ | |||
| const StringArray& getAllKeys() const noexcept { return keys; } | |||
| @@ -81,7 +81,7 @@ namespace StringPoolHelpers | |||
| String::CharPointerType StringPool::getPooledString (const String& s) | |||
| { | |||
| if (s.isEmpty()) | |||
| return String::empty.getCharPointer(); | |||
| return String().getCharPointer(); | |||
| 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) | |||
| { | |||
| if (s == nullptr || *s == 0) | |||
| return String::empty.getCharPointer(); | |||
| return String().getCharPointer(); | |||
| 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) | |||
| { | |||
| if (s == nullptr || *s == 0) | |||
| return String::empty.getCharPointer(); | |||
| return String().getCharPointer(); | |||
| return StringPoolHelpers::getPooledStringFromArray (strings, s, lock); | |||
| } | |||
| @@ -221,7 +221,7 @@ bool Thread::setPriority (const int newPriority) | |||
| const ScopedLock sl (startStopLock); | |||
| if (setThreadPriority (threadHandle, newPriority)) | |||
| if ((! isThreadRunning()) || setThreadPriority (threadHandle, newPriority)) | |||
| { | |||
| threadPriority = newPriority; | |||
| return true; | |||
| @@ -210,7 +210,7 @@ public: | |||
| will wait for it to finish. | |||
| 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. | |||
| @param job the job to remove | |||
| @@ -247,7 +247,7 @@ public: | |||
| /** Returns one of the jobs in the queue. | |||
| 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; | |||
| @@ -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() | |||
| { | |||
| 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; | |||
| } | |||
| @@ -65,17 +65,16 @@ public: | |||
| */ | |||
| PerformanceCounter (const String& counterName, | |||
| int runsPerPrintout = 100, | |||
| const File& loggingFile = File::nonexistent); | |||
| const File& loggingFile = File()); | |||
| /** Destructor. */ | |||
| ~PerformanceCounter(); | |||
| //============================================================================== | |||
| /** Starts timing. | |||
| @see stop | |||
| */ | |||
| void start(); | |||
| void start() noexcept; | |||
| /** Stops timing and prints out the results. | |||
| @@ -84,7 +83,7 @@ public: | |||
| @see start | |||
| */ | |||
| void stop(); | |||
| bool stop(); | |||
| /** Dumps the current metrics to the debugger output and to a file. | |||
| @@ -94,13 +93,35 @@ public: | |||
| */ | |||
| 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: | |||
| //============================================================================== | |||
| String name; | |||
| int numRuns, runsPerPrint; | |||
| double totalTime; | |||
| int64 started; | |||
| Statistics stats; | |||
| int64 runsPerPrint, startTime; | |||
| File outputFile; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PerformanceCounter) | |||
| }; | |||
| #endif // JUCE_PERFORMANCECOUNTER_H_INCLUDED | |||
| @@ -110,7 +110,7 @@ namespace TimeHelpers | |||
| const size_t numChars = wcsftime (buffer, bufferSize - 1, format.toUTF32(), tm); | |||
| #endif | |||
| if (numChars > 0) | |||
| if (numChars > 0 || format.isEmpty()) | |||
| return String (StringType (buffer), | |||
| StringType (buffer) + (int) numChars); | |||
| } | |||
| @@ -210,7 +210,7 @@ XmlElement* XmlDocument::parseDocumentElement (String::CharPointerType textToPar | |||
| } | |||
| else | |||
| { | |||
| lastError = String::empty; | |||
| lastError.clear(); | |||
| ScopedPointer<XmlElement> result (readNextElement (! onlyReadOuterDocumentElement)); | |||
| @@ -285,10 +285,3 @@ bool GZIPDecompressorInputStream::setPosition (int64 newPos) | |||
| skipNextBytes (newPos - currentPos); | |||
| 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); | |||
| } | |||
| @@ -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 | |||
| { | |||
| 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: | |||
| const File file; | |||
| ScopedPointer<InputStream> stream; | |||
| String storedPathname; | |||
| int compressionLevel, compressedSize, headerStart; | |||
| Time fileTime; | |||
| int compressionLevel, compressedSize, uncompressedSize, headerStart; | |||
| 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.getDayOfMonth() + ((t.getMonth() + 1) << 5) + ((t.getYear() - 1980) << 9))); | |||
| } | |||
| 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); | |||
| while (! input.isExhausted()) | |||
| while (! stream->isExhausted()) | |||
| { | |||
| const int bytesRead = input.read (buffer, bufferSize); | |||
| const int bytesRead = stream->read (buffer, bufferSize); | |||
| if (bytesRead < 0) | |||
| return false; | |||
| checksum = juce_crc32 (checksum, buffer, (unsigned int) bytesRead); | |||
| checksum = zlibNamespace::crc32 (checksum, buffer, (unsigned int) bytesRead); | |||
| target.write (buffer, (size_t) bytesRead); | |||
| uncompressedSize += bytesRead; | |||
| } | |||
| stream = nullptr; | |||
| return true; | |||
| } | |||
| void writeFlagsAndSizes (OutputStream& target) const | |||
| { | |||
| 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); | |||
| writeTimeAndDate (target); | |||
| writeTimeAndDate (target, fileTime); | |||
| target.writeInt ((int) checksum); | |||
| target.writeInt (compressedSize); | |||
| target.writeInt ((int) file.getSize()); | |||
| target.writeInt (uncompressedSize); | |||
| target.writeShort ((short) storedPathname.toUTF8().sizeInBytes() - 1); | |||
| target.writeShort (0); // extra field length | |||
| } | |||
| @@ -556,9 +558,18 @@ private: | |||
| 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 | |||
| @@ -196,6 +196,21 @@ public: | |||
| void addFile (const File& fileToAdd, int compressionLevel, | |||
| 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. | |||
| If the progress parameter is non-null, it will be updated with an approximate | |||
| progress status between 0 and 1.0 | |||
| @@ -251,8 +251,8 @@ unsigned long ZEXPORT crc32 (unsigned long crc, const unsigned char FAR *buf, un | |||
| /* ========================================================================= */ | |||
| #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 | |||
| /* ========================================================================= */ | |||
| @@ -264,7 +264,7 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf | |||
| c = (u4)crc; | |||
| c = ~c; | |||
| 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--; | |||
| } | |||
| @@ -280,7 +280,7 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf | |||
| buf = (const unsigned char FAR *)buf4; | |||
| if (len) do { | |||
| c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); | |||
| c = (u4) (crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8)); | |||
| } while (--len); | |||
| c = ~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; \ | |||
| 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 | |||
| /* ========================================================================= */ | |||
| @@ -301,7 +301,7 @@ local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf, | |||
| c = REV((u4)crc); | |||
| c = ~c; | |||
| 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--; | |||
| } | |||
| @@ -319,7 +319,7 @@ local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf, | |||
| buf = (const unsigned char FAR *)buf4; | |||
| 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); | |||
| c = ~c; | |||
| return (unsigned long)(REV(c)); | |||
| @@ -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; | |||
| state = (struct inflate_state FAR *)strm->state; | |||
| 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->bits += bits; | |||
| return Z_OK; | |||
| @@ -203,7 +203,7 @@ local void send_bits (deflate_state *s, int value, int length) | |||
| s->bi_buf |= (value << s->bi_valid); | |||
| put_short(s, s->bi_buf); | |||
| s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); | |||
| s->bi_valid += length - Buf_size; | |||
| s->bi_valid += (int) (length - Buf_size); | |||
| } else { | |||
| s->bi_buf |= value << s->bi_valid; | |||
| s->bi_valid += length; | |||