| @@ -131,56 +131,38 @@ void PluginListComponent::deleteKeyPressed (int lastRowSelected) | |||||
| list.removeType (lastRowSelected); | list.removeType (lastRowSelected); | ||||
| } | } | ||||
| void PluginListComponent::buttonClicked (Button* button) | |||||
| void PluginListComponent::optionsMenuCallback (int result) | |||||
| { | { | ||||
| if (button == &optionsButton) | |||||
| switch (result) | |||||
| { | { | ||||
| PopupMenu menu; | |||||
| menu.addItem (1, TRANS("Clear list")); | |||||
| menu.addItem (5, TRANS("Remove selected plugin from list"), listBox.getNumSelectedRows() > 0); | |||||
| menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox.getNumSelectedRows() > 0); | |||||
| menu.addItem (7, TRANS("Remove any plugins whose files no longer exist")); | |||||
| menu.addSeparator(); | |||||
| menu.addItem (2, TRANS("Sort alphabetically")); | |||||
| menu.addItem (3, TRANS("Sort by category")); | |||||
| menu.addItem (4, TRANS("Sort by manufacturer")); | |||||
| menu.addSeparator(); | |||||
| for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i) | |||||
| { | |||||
| AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i); | |||||
| if (format->getDefaultLocationsToSearch().getNumPaths() > 0) | |||||
| menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plugins..."); | |||||
| } | |||||
| const int r = menu.showMenu (PopupMenu::Options().withTargetComponent (&optionsButton)); | |||||
| if (r == 1) | |||||
| { | |||||
| case 1: | |||||
| list.clear(); | list.clear(); | ||||
| } | |||||
| else if (r == 2) | |||||
| { | |||||
| break; | |||||
| case 2: | |||||
| list.sort (KnownPluginList::sortAlphabetically); | list.sort (KnownPluginList::sortAlphabetically); | ||||
| } | |||||
| else if (r == 3) | |||||
| { | |||||
| break; | |||||
| case 3: | |||||
| list.sort (KnownPluginList::sortByCategory); | list.sort (KnownPluginList::sortByCategory); | ||||
| } | |||||
| else if (r == 4) | |||||
| { | |||||
| break; | |||||
| case 4: | |||||
| list.sort (KnownPluginList::sortByManufacturer); | list.sort (KnownPluginList::sortByManufacturer); | ||||
| } | |||||
| else if (r == 5) | |||||
| break; | |||||
| case 5: | |||||
| { | { | ||||
| const SparseSet <int> selected (listBox.getSelectedRows()); | const SparseSet <int> selected (listBox.getSelectedRows()); | ||||
| for (int i = list.getNumTypes(); --i >= 0;) | for (int i = list.getNumTypes(); --i >= 0;) | ||||
| if (selected.contains (i)) | if (selected.contains (i)) | ||||
| list.removeType (i); | list.removeType (i); | ||||
| break; | |||||
| } | } | ||||
| else if (r == 6) | |||||
| case 6: | |||||
| { | { | ||||
| const PluginDescription* const desc = list.getType (listBox.getSelectedRow()); | const PluginDescription* const desc = list.getType (listBox.getSelectedRow()); | ||||
| @@ -189,22 +171,59 @@ void PluginListComponent::buttonClicked (Button* button) | |||||
| if (File (desc->fileOrIdentifier).existsAsFile()) | if (File (desc->fileOrIdentifier).existsAsFile()) | ||||
| File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); | File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); | ||||
| } | } | ||||
| break; | |||||
| } | } | ||||
| else if (r == 7) | |||||
| { | |||||
| case 7: | |||||
| for (int i = list.getNumTypes(); --i >= 0;) | for (int i = list.getNumTypes(); --i >= 0;) | ||||
| { | |||||
| if (! AudioPluginFormatManager::getInstance()->doesPluginStillExist (*list.getType (i))) | if (! AudioPluginFormatManager::getInstance()->doesPluginStillExist (*list.getType (i))) | ||||
| { | |||||
| list.removeType (i); | list.removeType (i); | ||||
| } | |||||
| break; | |||||
| default: | |||||
| if (result != 0) | |||||
| { | |||||
| typeToScan = result - 10; | |||||
| startTimer (1); | |||||
| } | } | ||||
| } | |||||
| else if (r != 0) | |||||
| break; | |||||
| } | |||||
| } | |||||
| void PluginListComponent::optionsMenuStaticCallback (int result, PluginListComponent* pluginList) | |||||
| { | |||||
| if (pluginList != 0) | |||||
| pluginList->optionsMenuCallback (result); | |||||
| } | |||||
| void PluginListComponent::buttonClicked (Button* button) | |||||
| { | |||||
| if (button == &optionsButton) | |||||
| { | |||||
| PopupMenu menu; | |||||
| menu.addItem (1, TRANS("Clear list")); | |||||
| menu.addItem (5, TRANS("Remove selected plugin from list"), listBox.getNumSelectedRows() > 0); | |||||
| menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox.getNumSelectedRows() > 0); | |||||
| menu.addItem (7, TRANS("Remove any plugins whose files no longer exist")); | |||||
| menu.addSeparator(); | |||||
| menu.addItem (2, TRANS("Sort alphabetically")); | |||||
| menu.addItem (3, TRANS("Sort by category")); | |||||
| menu.addItem (4, TRANS("Sort by manufacturer")); | |||||
| menu.addSeparator(); | |||||
| for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i) | |||||
| { | { | ||||
| typeToScan = r - 10; | |||||
| startTimer (1); | |||||
| AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i); | |||||
| if (format->getDefaultLocationsToSearch().getNumPaths() > 0) | |||||
| menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plugins..."); | |||||
| } | } | ||||
| menu.showMenuAsync (PopupMenu::Options().withTargetComponent (&optionsButton), | |||||
| ModalCallbackFunction::forComponent (optionsMenuStaticCallback, this)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -90,6 +90,8 @@ private: | |||||
| int typeToScan; | int typeToScan; | ||||
| void scanFor (AudioPluginFormat* format); | void scanFor (AudioPluginFormat* format); | ||||
| static void optionsMenuStaticCallback (int result, PluginListComponent*); | |||||
| void optionsMenuCallback (int result); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent); | ||||
| }; | }; | ||||
| @@ -31,6 +31,15 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_DynamicObject.h" | #include "juce_DynamicObject.h" | ||||
| #include "../io/streams/juce_MemoryOutputStream.h" | #include "../io/streams/juce_MemoryOutputStream.h" | ||||
| enum VariantStreamMarkers | |||||
| { | |||||
| varMarker_Int = 1, | |||||
| varMarker_BoolTrue = 2, | |||||
| varMarker_BoolFalse = 3, | |||||
| varMarker_Double = 4, | |||||
| varMarker_String = 5, | |||||
| varMarker_Int64 = 6 | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| class var::VariantType | class var::VariantType | ||||
| @@ -40,6 +49,7 @@ public: | |||||
| virtual ~VariantType() {} | virtual ~VariantType() {} | ||||
| virtual int toInt (const ValueUnion&) const { return 0; } | virtual int toInt (const ValueUnion&) const { return 0; } | ||||
| virtual int64 toInt64 (const ValueUnion&) const { return 0; } | |||||
| virtual double toDouble (const ValueUnion&) const { return 0; } | virtual double toDouble (const ValueUnion&) const { return 0; } | ||||
| virtual const String toString (const ValueUnion&) const { return String::empty; } | virtual const String toString (const ValueUnion&) const { return String::empty; } | ||||
| virtual bool toBool (const ValueUnion&) const { return false; } | virtual bool toBool (const ValueUnion&) const { return false; } | ||||
| @@ -47,6 +57,7 @@ public: | |||||
| virtual bool isVoid() const throw() { return false; } | virtual bool isVoid() const throw() { return false; } | ||||
| virtual bool isInt() const throw() { return false; } | virtual bool isInt() const throw() { return false; } | ||||
| virtual bool isInt64() const throw() { return false; } | |||||
| virtual bool isBool() const throw() { return false; } | virtual bool isBool() const throw() { return false; } | ||||
| virtual bool isDouble() const throw() { return false; } | virtual bool isDouble() const throw() { return false; } | ||||
| virtual bool isString() const throw() { return false; } | virtual bool isString() const throw() { return false; } | ||||
| @@ -79,6 +90,7 @@ public: | |||||
| static const VariantType_Int instance; | static const VariantType_Int instance; | ||||
| int toInt (const ValueUnion& data) const { return data.intValue; }; | int toInt (const ValueUnion& data) const { return data.intValue; }; | ||||
| int64 toInt64 (const ValueUnion& data) const { return (int64) data.intValue; }; | |||||
| double toDouble (const ValueUnion& data) const { return (double) data.intValue; } | double toDouble (const ValueUnion& data) const { return (double) data.intValue; } | ||||
| const String toString (const ValueUnion& data) const { return String (data.intValue); } | const String toString (const ValueUnion& data) const { return String (data.intValue); } | ||||
| bool toBool (const ValueUnion& data) const { return data.intValue != 0; } | bool toBool (const ValueUnion& data) const { return data.intValue != 0; } | ||||
| @@ -92,11 +104,38 @@ public: | |||||
| void writeToStream (const ValueUnion& data, OutputStream& output) const | void writeToStream (const ValueUnion& data, OutputStream& output) const | ||||
| { | { | ||||
| output.writeCompressedInt (5); | output.writeCompressedInt (5); | ||||
| output.writeByte (1); | |||||
| output.writeByte (varMarker_Int); | |||||
| output.writeInt (data.intValue); | output.writeInt (data.intValue); | ||||
| } | } | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| class var::VariantType_Int64 : public var::VariantType | |||||
| { | |||||
| public: | |||||
| VariantType_Int64() {} | |||||
| static const VariantType_Int64 instance; | |||||
| int toInt (const ValueUnion& data) const { return (int) data.int64Value; }; | |||||
| int64 toInt64 (const ValueUnion& data) const { return data.int64Value; }; | |||||
| double toDouble (const ValueUnion& data) const { return (double) data.int64Value; } | |||||
| const String toString (const ValueUnion& data) const { return String (data.int64Value); } | |||||
| bool toBool (const ValueUnion& data) const { return data.int64Value != 0; } | |||||
| bool isInt64() const throw() { return true; } | |||||
| bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() | |||||
| { | |||||
| return otherType.toInt64 (otherData) == data.int64Value; | |||||
| } | |||||
| void writeToStream (const ValueUnion& data, OutputStream& output) const | |||||
| { | |||||
| output.writeCompressedInt (9); | |||||
| output.writeByte (varMarker_Int64); | |||||
| output.writeInt64 (data.int64Value); | |||||
| } | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| class var::VariantType_Double : public var::VariantType | class var::VariantType_Double : public var::VariantType | ||||
| { | { | ||||
| @@ -105,6 +144,7 @@ public: | |||||
| static const VariantType_Double instance; | static const VariantType_Double instance; | ||||
| int toInt (const ValueUnion& data) const { return (int) data.doubleValue; }; | int toInt (const ValueUnion& data) const { return (int) data.doubleValue; }; | ||||
| int64 toInt64 (const ValueUnion& data) const { return (int64) data.doubleValue; }; | |||||
| double toDouble (const ValueUnion& data) const { return data.doubleValue; } | double toDouble (const ValueUnion& data) const { return data.doubleValue; } | ||||
| const String toString (const ValueUnion& data) const { return String (data.doubleValue); } | const String toString (const ValueUnion& data) const { return String (data.doubleValue); } | ||||
| bool toBool (const ValueUnion& data) const { return data.doubleValue != 0; } | bool toBool (const ValueUnion& data) const { return data.doubleValue != 0; } | ||||
| @@ -118,7 +158,7 @@ public: | |||||
| void writeToStream (const ValueUnion& data, OutputStream& output) const | void writeToStream (const ValueUnion& data, OutputStream& output) const | ||||
| { | { | ||||
| output.writeCompressedInt (9); | output.writeCompressedInt (9); | ||||
| output.writeByte (4); | |||||
| output.writeByte (varMarker_Double); | |||||
| output.writeDouble (data.doubleValue); | output.writeDouble (data.doubleValue); | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -131,6 +171,7 @@ public: | |||||
| static const VariantType_Bool instance; | static const VariantType_Bool instance; | ||||
| int toInt (const ValueUnion& data) const { return data.boolValue ? 1 : 0; }; | int toInt (const ValueUnion& data) const { return data.boolValue ? 1 : 0; }; | ||||
| int64 toInt64 (const ValueUnion& data) const { return data.boolValue ? 1 : 0; }; | |||||
| double toDouble (const ValueUnion& data) const { return data.boolValue ? 1.0 : 0.0; } | double toDouble (const ValueUnion& data) const { return data.boolValue ? 1.0 : 0.0; } | ||||
| const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); } | const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); } | ||||
| bool toBool (const ValueUnion& data) const { return data.boolValue; } | bool toBool (const ValueUnion& data) const { return data.boolValue; } | ||||
| @@ -144,7 +185,7 @@ public: | |||||
| void writeToStream (const ValueUnion& data, OutputStream& output) const | void writeToStream (const ValueUnion& data, OutputStream& output) const | ||||
| { | { | ||||
| output.writeCompressedInt (1); | output.writeCompressedInt (1); | ||||
| output.writeByte (data.boolValue ? 2 : 3); | |||||
| output.writeByte (data.boolValue ? varMarker_BoolTrue : varMarker_BoolFalse); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -159,6 +200,7 @@ public: | |||||
| void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.stringValue = new String (*source.stringValue); } | void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.stringValue = new String (*source.stringValue); } | ||||
| int toInt (const ValueUnion& data) const { return data.stringValue->getIntValue(); }; | int toInt (const ValueUnion& data) const { return data.stringValue->getIntValue(); }; | ||||
| int64 toInt64 (const ValueUnion& data) const { return data.stringValue->getLargeIntValue(); }; | |||||
| double toDouble (const ValueUnion& data) const { return data.stringValue->getDoubleValue(); } | double toDouble (const ValueUnion& data) const { return data.stringValue->getDoubleValue(); } | ||||
| const String toString (const ValueUnion& data) const { return *data.stringValue; } | const String toString (const ValueUnion& data) const { return *data.stringValue; } | ||||
| bool toBool (const ValueUnion& data) const { return data.stringValue->getIntValue() != 0 | bool toBool (const ValueUnion& data) const { return data.stringValue->getIntValue() != 0 | ||||
| @@ -175,7 +217,7 @@ public: | |||||
| { | { | ||||
| const int len = data.stringValue->getNumBytesAsUTF8() + 1; | const int len = data.stringValue->getNumBytesAsUTF8() + 1; | ||||
| output.writeCompressedInt (len + 1); | output.writeCompressedInt (len + 1); | ||||
| output.writeByte (5); | |||||
| output.writeByte (varMarker_String); | |||||
| HeapBlock<char> temp (len); | HeapBlock<char> temp (len); | ||||
| data.stringValue->copyToUTF8 (temp, len); | data.stringValue->copyToUTF8 (temp, len); | ||||
| output.write (temp, len); | output.write (temp, len); | ||||
| @@ -235,6 +277,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| const var::VariantType_Void var::VariantType_Void::instance; | const var::VariantType_Void var::VariantType_Void::instance; | ||||
| const var::VariantType_Int var::VariantType_Int::instance; | const var::VariantType_Int var::VariantType_Int::instance; | ||||
| const var::VariantType_Int64 var::VariantType_Int64::instance; | |||||
| const var::VariantType_Bool var::VariantType_Bool::instance; | const var::VariantType_Bool var::VariantType_Bool::instance; | ||||
| const var::VariantType_Double var::VariantType_Double::instance; | const var::VariantType_Double var::VariantType_Double::instance; | ||||
| const var::VariantType_String var::VariantType_String::instance; | const var::VariantType_String var::VariantType_String::instance; | ||||
| @@ -265,6 +308,11 @@ var::var (const int value_) throw() : type (&VariantType_Int::instance) | |||||
| value.intValue = value_; | value.intValue = value_; | ||||
| } | } | ||||
| var::var (const int64 value_) throw() : type (&VariantType_Int64::instance) | |||||
| { | |||||
| value.intValue = value_; | |||||
| } | |||||
| var::var (const bool value_) throw() : type (&VariantType_Bool::instance) | var::var (const bool value_) throw() : type (&VariantType_Bool::instance) | ||||
| { | { | ||||
| value.boolValue = value_; | value.boolValue = value_; | ||||
| @@ -306,6 +354,7 @@ var::var (MethodFunction method_) throw() : type (&VariantType_Method::instance | |||||
| //============================================================================== | //============================================================================== | ||||
| bool var::isVoid() const throw() { return type->isVoid(); } | bool var::isVoid() const throw() { return type->isVoid(); } | ||||
| bool var::isInt() const throw() { return type->isInt(); } | bool var::isInt() const throw() { return type->isInt(); } | ||||
| bool var::isInt64() const throw() { return type->isInt64(); } | |||||
| bool var::isBool() const throw() { return type->isBool(); } | bool var::isBool() const throw() { return type->isBool(); } | ||||
| bool var::isDouble() const throw() { return type->isDouble(); } | bool var::isDouble() const throw() { return type->isDouble(); } | ||||
| bool var::isString() const throw() { return type->isString(); } | bool var::isString() const throw() { return type->isString(); } | ||||
| @@ -313,6 +362,7 @@ bool var::isObject() const throw() { return type->isObject(); } | |||||
| bool var::isMethod() const throw() { return type->isMethod(); } | bool var::isMethod() const throw() { return type->isMethod(); } | ||||
| var::operator int() const { return type->toInt (value); } | var::operator int() const { return type->toInt (value); } | ||||
| var::operator int64() const { return type->toInt64 (value); } | |||||
| var::operator bool() const { return type->toBool (value); } | var::operator bool() const { return type->toBool (value); } | ||||
| var::operator float() const { return (float) type->toDouble (value); } | var::operator float() const { return (float) type->toDouble (value); } | ||||
| var::operator double() const { return type->toDouble (value); } | var::operator double() const { return type->toDouble (value); } | ||||
| @@ -329,6 +379,7 @@ void var::swapWith (var& other) throw() | |||||
| var& var::operator= (const var& newValue) { type->cleanUp (value); type = newValue.type; type->createCopy (value, newValue.value); return *this; } | var& var::operator= (const var& newValue) { type->cleanUp (value); type = newValue.type; type->createCopy (value, newValue.value); return *this; } | ||||
| var& var::operator= (int newValue) { var v (newValue); swapWith (v); return *this; } | var& var::operator= (int newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| var& var::operator= (int64 newValue) { var v (newValue); swapWith (v); return *this; } | |||||
| var& var::operator= (bool newValue) { var v (newValue); swapWith (v); return *this; } | var& var::operator= (bool newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| var& var::operator= (double newValue) { var v (newValue); swapWith (v); return *this; } | var& var::operator= (double newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| var& var::operator= (const char* newValue) { var v (newValue); swapWith (v); return *this; } | var& var::operator= (const char* newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| @@ -367,11 +418,12 @@ const var var::readFromStream (InputStream& input) | |||||
| { | { | ||||
| switch (input.readByte()) | switch (input.readByte()) | ||||
| { | { | ||||
| case 1: return var (input.readInt()); | |||||
| case 2: return var (true); | |||||
| case 3: return var (false); | |||||
| case 4: return var (input.readDouble()); | |||||
| case 5: | |||||
| case varMarker_Int: return var (input.readInt()); | |||||
| case varMarker_Int64: return var (input.readInt64()); | |||||
| case varMarker_BoolTrue: return var (true); | |||||
| case varMarker_BoolFalse: return var (false); | |||||
| case varMarker_Double: return var (input.readDouble()); | |||||
| case varMarker_String: | |||||
| { | { | ||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| mo.writeFromInputStream (input, numBytes - 1); | mo.writeFromInputStream (input, numBytes - 1); | ||||
| @@ -63,6 +63,7 @@ public: | |||||
| var (const var& valueToCopy); | var (const var& valueToCopy); | ||||
| var (int value) throw(); | var (int value) throw(); | ||||
| var (int64 value) throw(); | |||||
| var (bool value) throw(); | var (bool value) throw(); | ||||
| var (double value) throw(); | var (double value) throw(); | ||||
| var (const char* value); | var (const char* value); | ||||
| @@ -73,6 +74,7 @@ public: | |||||
| var& operator= (const var& valueToCopy); | var& operator= (const var& valueToCopy); | ||||
| var& operator= (int value); | var& operator= (int value); | ||||
| var& operator= (int64 value); | |||||
| var& operator= (bool value); | var& operator= (bool value); | ||||
| var& operator= (double value); | var& operator= (double value); | ||||
| var& operator= (const char* value); | var& operator= (const char* value); | ||||
| @@ -84,6 +86,7 @@ public: | |||||
| void swapWith (var& other) throw(); | void swapWith (var& other) throw(); | ||||
| operator int() const; | operator int() const; | ||||
| operator int64() const; | |||||
| operator bool() const; | operator bool() const; | ||||
| operator float() const; | operator float() const; | ||||
| operator double() const; | operator double() const; | ||||
| @@ -93,6 +96,7 @@ public: | |||||
| bool isVoid() const throw(); | bool isVoid() const throw(); | ||||
| bool isInt() const throw(); | bool isInt() const throw(); | ||||
| bool isInt64() const throw(); | |||||
| bool isBool() const throw(); | bool isBool() const throw(); | ||||
| bool isDouble() const throw(); | bool isDouble() const throw(); | ||||
| bool isString() const throw(); | bool isString() const throw(); | ||||
| @@ -152,6 +156,8 @@ private: | |||||
| friend class VariantType_Void; | friend class VariantType_Void; | ||||
| class VariantType_Int; | class VariantType_Int; | ||||
| friend class VariantType_Int; | friend class VariantType_Int; | ||||
| class VariantType_Int64; | |||||
| friend class VariantType_Int64; | |||||
| class VariantType_Double; | class VariantType_Double; | ||||
| friend class VariantType_Double; | friend class VariantType_Double; | ||||
| class VariantType_Float; | class VariantType_Float; | ||||
| @@ -168,6 +174,7 @@ private: | |||||
| union ValueUnion | union ValueUnion | ||||
| { | { | ||||
| int intValue; | int intValue; | ||||
| int64 int64Value; | |||||
| bool boolValue; | bool boolValue; | ||||
| double doubleValue; | double doubleValue; | ||||
| String* stringValue; | String* stringValue; | ||||
| @@ -117,10 +117,7 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) | |||||
| bytesNeeded, &bytesRead, | bytesNeeded, &bytesRead, | ||||
| &outputBufferSize, tempOut) == noErr) | &outputBufferSize, tempOut) == noErr) | ||||
| { | { | ||||
| result.preallocateStorage (bytesRead / sizeof (UniChar) + 2); | |||||
| CharPointer_UTF32 dest (result.getCharPointer()); | |||||
| dest.writeAll (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData())); | |||||
| result = String (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData())); | |||||
| } | } | ||||
| DisposeUnicodeToTextInfo (&conversionInfo); | DisposeUnicodeToTextInfo (&conversionInfo); | ||||
| @@ -64,16 +64,12 @@ public: | |||||
| } | } | ||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | /** This is a pointer comparison, it doesn't compare the actual text. */ | ||||
| inline bool operator== (const CharPointer_ASCII& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | |||||
| inline bool operator!= (const CharPointer_ASCII& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| inline bool operator== (const CharPointer_ASCII& other) const throw() { return data == other.data; } | |||||
| inline bool operator!= (const CharPointer_ASCII& other) const throw() { return data != other.data; } | |||||
| inline bool operator<= (const CharPointer_ASCII& other) const throw() { return data <= other.data; } | |||||
| inline bool operator< (const CharPointer_ASCII& other) const throw() { return data < other.data; } | |||||
| inline bool operator>= (const CharPointer_ASCII& other) const throw() { return data >= other.data; } | |||||
| inline bool operator> (const CharPointer_ASCII& other) const throw() { return data > other.data; } | |||||
| /** Returns the address that this pointer is pointing to. */ | /** Returns the address that this pointer is pointing to. */ | ||||
| inline CharType* getAddress() const throw() { return data; } | inline CharType* getAddress() const throw() { return data; } | ||||
| @@ -171,6 +167,12 @@ public: | |||||
| return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | ||||
| } | } | ||||
| /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ | |||||
| size_t lengthUpTo (const CharPointer_ASCII& end) const throw() | |||||
| { | |||||
| return CharacterFunctions::lengthUpTo (*this, end); | |||||
| } | |||||
| /** Returns the number of bytes that are used to represent this string. | /** Returns the number of bytes that are used to represent this string. | ||||
| This includes the terminating null character. | This includes the terminating null character. | ||||
| */ | */ | ||||
| @@ -65,16 +65,12 @@ public: | |||||
| } | } | ||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | /** This is a pointer comparison, it doesn't compare the actual text. */ | ||||
| inline bool operator== (const CharPointer_UTF16& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | |||||
| inline bool operator!= (const CharPointer_UTF16& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| inline bool operator== (const CharPointer_UTF16& other) const throw() { return data == other.data; } | |||||
| inline bool operator!= (const CharPointer_UTF16& other) const throw() { return data != other.data; } | |||||
| inline bool operator<= (const CharPointer_UTF16& other) const throw() { return data <= other.data; } | |||||
| inline bool operator< (const CharPointer_UTF16& other) const throw() { return data < other.data; } | |||||
| inline bool operator>= (const CharPointer_UTF16& other) const throw() { return data >= other.data; } | |||||
| inline bool operator> (const CharPointer_UTF16& other) const throw() { return data > other.data; } | |||||
| /** Returns the address that this pointer is pointing to. */ | /** Returns the address that this pointer is pointing to. */ | ||||
| inline CharType* getAddress() const throw() { return data; } | inline CharType* getAddress() const throw() { return data; } | ||||
| @@ -203,6 +199,12 @@ public: | |||||
| return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | ||||
| } | } | ||||
| /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ | |||||
| size_t lengthUpTo (const CharPointer_UTF16& end) const throw() | |||||
| { | |||||
| return CharacterFunctions::lengthUpTo (*this, end); | |||||
| } | |||||
| /** Returns the number of bytes that are used to represent this string. | /** Returns the number of bytes that are used to represent this string. | ||||
| This includes the terminating null character. | This includes the terminating null character. | ||||
| */ | */ | ||||
| @@ -61,16 +61,12 @@ public: | |||||
| } | } | ||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | /** This is a pointer comparison, it doesn't compare the actual text. */ | ||||
| inline bool operator== (const CharPointer_UTF32& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | |||||
| inline bool operator!= (const CharPointer_UTF32& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| inline bool operator== (const CharPointer_UTF32& other) const throw() { return data == other.data; } | |||||
| inline bool operator!= (const CharPointer_UTF32& other) const throw() { return data != other.data; } | |||||
| inline bool operator<= (const CharPointer_UTF32& other) const throw() { return data <= other.data; } | |||||
| inline bool operator< (const CharPointer_UTF32& other) const throw() { return data < other.data; } | |||||
| inline bool operator>= (const CharPointer_UTF32& other) const throw() { return data >= other.data; } | |||||
| inline bool operator> (const CharPointer_UTF32& other) const throw() { return data > other.data; } | |||||
| /** Returns the address that this pointer is pointing to. */ | /** Returns the address that this pointer is pointing to. */ | ||||
| inline CharType* getAddress() const throw() { return data; } | inline CharType* getAddress() const throw() { return data; } | ||||
| @@ -175,6 +171,12 @@ public: | |||||
| return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | ||||
| } | } | ||||
| /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ | |||||
| size_t lengthUpTo (const CharPointer_UTF32& end) const throw() | |||||
| { | |||||
| return CharacterFunctions::lengthUpTo (*this, end); | |||||
| } | |||||
| /** Returns the number of bytes that are used to represent this string. | /** Returns the number of bytes that are used to represent this string. | ||||
| This includes the terminating null character. | This includes the terminating null character. | ||||
| */ | */ | ||||
| @@ -60,16 +60,12 @@ public: | |||||
| } | } | ||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | /** This is a pointer comparison, it doesn't compare the actual text. */ | ||||
| inline bool operator== (const CharPointer_UTF8& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| /** This is a pointer comparison, it doesn't compare the actual text. */ | |||||
| inline bool operator!= (const CharPointer_UTF8& other) const throw() | |||||
| { | |||||
| return data == other.data; | |||||
| } | |||||
| inline bool operator== (const CharPointer_UTF8& other) const throw() { return data == other.data; } | |||||
| inline bool operator!= (const CharPointer_UTF8& other) const throw() { return data != other.data; } | |||||
| inline bool operator<= (const CharPointer_UTF8& other) const throw() { return data <= other.data; } | |||||
| inline bool operator< (const CharPointer_UTF8& other) const throw() { return data < other.data; } | |||||
| inline bool operator>= (const CharPointer_UTF8& other) const throw() { return data >= other.data; } | |||||
| inline bool operator> (const CharPointer_UTF8& other) const throw() { return data > other.data; } | |||||
| /** Returns the address that this pointer is pointing to. */ | /** Returns the address that this pointer is pointing to. */ | ||||
| inline CharType* getAddress() const throw() { return data; } | inline CharType* getAddress() const throw() { return data; } | ||||
| @@ -243,6 +239,12 @@ public: | |||||
| return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); | ||||
| } | } | ||||
| /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ | |||||
| size_t lengthUpTo (const CharPointer_UTF8& end) const throw() | |||||
| { | |||||
| return CharacterFunctions::lengthUpTo (*this, end); | |||||
| } | |||||
| /** Returns the number of bytes that are used to represent this string. | /** Returns the number of bytes that are used to represent this string. | ||||
| This includes the terminating null character. | This includes the terminating null character. | ||||
| */ | */ | ||||
| @@ -272,17 +272,26 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| template <typename CharPointerType> | template <typename CharPointerType> | ||||
| static size_t lengthUpTo (const CharPointerType& text, const size_t maxCharsToCount) throw() | |||||
| static size_t lengthUpTo (CharPointerType text, const size_t maxCharsToCount) throw() | |||||
| { | { | ||||
| size_t len = 0; | size_t len = 0; | ||||
| CharPointerType t (text); | |||||
| while (len < maxCharsToCount && t.getAndAdvance() != 0) | |||||
| while (len < maxCharsToCount && text.getAndAdvance() != 0) | |||||
| ++len; | ++len; | ||||
| return len; | return len; | ||||
| } | } | ||||
| template <typename CharPointerType> | |||||
| static size_t lengthUpTo (CharPointerType start, const CharPointerType& end) throw() | |||||
| { | |||||
| size_t len = 0; | |||||
| while (start < end && start.getAndAdvance() != 0) | |||||
| ++len; | |||||
| return len; | |||||
| } | |||||
| template <typename DestCharPointerType, typename SrcCharPointerType> | template <typename DestCharPointerType, typename SrcCharPointerType> | ||||
| static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) throw() | static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) throw() | ||||
| @@ -100,6 +100,21 @@ public: | |||||
| return dest; | return dest; | ||||
| } | } | ||||
| template <class CharPointer> | |||||
| static const CharPointerType createFromCharPointer (const CharPointer& start, const CharPointer& end) | |||||
| { | |||||
| if (start.getAddress() == 0 || start.isEmpty()) | |||||
| return getEmpty(); | |||||
| size_t numChars = start.lengthUpTo (end); | |||||
| if (numChars == 0) | |||||
| return getEmpty(); | |||||
| const CharPointerType dest (createUninitialised (numChars)); | |||||
| CharPointerType (dest).writeWithCharLimit (start, (int) (numChars + 1)); | |||||
| return dest; | |||||
| } | |||||
| static CharPointerType createFromFixedLength (const juce_wchar* const src, const size_t numChars) | static CharPointerType createFromFixedLength (const juce_wchar* const src, const size_t numChars) | ||||
| { | { | ||||
| CharPointerType dest (createUninitialised (numChars)); | CharPointerType dest (createUninitialised (numChars)); | ||||
| @@ -325,6 +340,11 @@ String::String (const CharPointer_UTF32& t, const size_t maxChars) | |||||
| { | { | ||||
| } | } | ||||
| String::String (const CharPointer_UTF32& start, const CharPointer_UTF32& end) | |||||
| : text (StringHolder::createFromCharPointer (start, end)) | |||||
| { | |||||
| } | |||||
| String::String (const CharPointer_ASCII& t) | String::String (const CharPointer_ASCII& t) | ||||
| : text (StringHolder::createFromCharPointer (t)) | : text (StringHolder::createFromCharPointer (t)) | ||||
| { | { | ||||
| @@ -347,8 +367,9 @@ String::String (const wchar_t* const t, size_t maxChars) | |||||
| const String String::charToString (const juce_wchar character) | const String String::charToString (const juce_wchar character) | ||||
| { | { | ||||
| String result (Preallocation (1)); | String result (Preallocation (1)); | ||||
| result.text[0] = character; | |||||
| result.text[1] = 0; | |||||
| CharPointerType t (result.text); | |||||
| t.write (character); | |||||
| t.writeNull(); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -540,22 +561,22 @@ const juce_wchar String::operator[] (int index) const throw() | |||||
| int String::hashCode() const throw() | int String::hashCode() const throw() | ||||
| { | { | ||||
| const juce_wchar* t = text; | |||||
| CharPointerType t (text); | |||||
| int result = 0; | int result = 0; | ||||
| while (*t != (juce_wchar) 0) | |||||
| result = 31 * result + *t++; | |||||
| while (! t.isEmpty()) | |||||
| result = 31 * result + t.getAndAdvance(); | |||||
| return result; | return result; | ||||
| } | } | ||||
| int64 String::hashCode64() const throw() | int64 String::hashCode64() const throw() | ||||
| { | { | ||||
| const juce_wchar* t = text; | |||||
| CharPointerType t (text); | |||||
| int64 result = 0; | int64 result = 0; | ||||
| while (*t != (juce_wchar) 0) | |||||
| result = 101 * result + *t++; | |||||
| while (! t.isEmpty()) | |||||
| result = 101 * result + t.getAndAdvance(); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -703,7 +724,6 @@ void String::append (const String& textToAppend, size_t maxCharsToTake) | |||||
| String& String::operator+= (const juce_wchar* const t) | String& String::operator+= (const juce_wchar* const t) | ||||
| { | { | ||||
| appendCharPointer (CharPointer_UTF32 (t)); | appendCharPointer (CharPointer_UTF32 (t)); | ||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -884,16 +904,7 @@ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&) | |||||
| //============================================================================== | //============================================================================== | ||||
| int String::indexOfChar (const juce_wchar character) const throw() | int String::indexOfChar (const juce_wchar character) const throw() | ||||
| { | { | ||||
| const juce_wchar* t = text; | |||||
| for (;;) | |||||
| { | |||||
| if (*t == character) | |||||
| return (int) (t - text); | |||||
| if (*t++ == 0) | |||||
| return -1; | |||||
| } | |||||
| return text.indexOf (character); | |||||
| } | } | ||||
| int String::lastIndexOfChar (const juce_wchar character) const throw() | int String::lastIndexOfChar (const juce_wchar character) const throw() | ||||
| @@ -913,21 +924,8 @@ int String::indexOf (const String& t) const throw() | |||||
| int String::indexOfChar (const int startIndex, | int String::indexOfChar (const int startIndex, | ||||
| const juce_wchar character) const throw() | const juce_wchar character) const throw() | ||||
| { | { | ||||
| if (startIndex > 0 && startIndex >= length()) | |||||
| return -1; | |||||
| const juce_wchar* t = text + jmax (0, startIndex); | |||||
| for (;;) | |||||
| { | |||||
| if (*t == character) | |||||
| return (int) (t - text); | |||||
| if (*t == 0) | |||||
| return -1; | |||||
| ++t; | |||||
| } | |||||
| const int i = (text + startIndex).indexOf (character); | |||||
| return i < 0 ? -1 : (i + startIndex); | |||||
| } | } | ||||
| int String::indexOfAnyOf (const String& charactersToLookFor, | int String::indexOfAnyOf (const String& charactersToLookFor, | ||||
| @@ -1058,18 +1056,7 @@ bool String::contains (const String& other) const throw() | |||||
| bool String::containsChar (const juce_wchar character) const throw() | bool String::containsChar (const juce_wchar character) const throw() | ||||
| { | { | ||||
| const juce_wchar* t = text; | |||||
| for (;;) | |||||
| { | |||||
| if (*t == 0) | |||||
| return false; | |||||
| if (*t == character) | |||||
| return true; | |||||
| ++t; | |||||
| } | |||||
| return text.indexOf (character) >= 0; | |||||
| } | } | ||||
| bool String::containsIgnoreCase (const String& t) const throw() | bool String::containsIgnoreCase (const String& t) const throw() | ||||
| @@ -1210,15 +1197,11 @@ const String String::repeatedString (const String& stringToRepeat, int numberOfT | |||||
| if (numberOfTimesToRepeat <= 0) | if (numberOfTimesToRepeat <= 0) | ||||
| return String::empty; | return String::empty; | ||||
| const int len = stringToRepeat.length(); | |||||
| String result (Preallocation (len * numberOfTimesToRepeat + 1)); | |||||
| String result (Preallocation (stringToRepeat.length() * numberOfTimesToRepeat + 1)); | |||||
| CharPointerType n (result.text); | CharPointerType n (result.text); | ||||
| while (--numberOfTimesToRepeat >= 0) | while (--numberOfTimesToRepeat >= 0) | ||||
| { | |||||
| StringHolder::copyChars (n, stringToRepeat.text, len); | |||||
| n += len; | |||||
| } | |||||
| n.writeAll (stringToRepeat.text); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -1602,57 +1585,63 @@ const String String::quoted (const juce_wchar quoteCharacter) const | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String String::trim() const | |||||
| static String::CharPointerType findTrimmedEnd (const String::CharPointerType& start, String::CharPointerType end) | |||||
| { | { | ||||
| if (isEmpty()) | |||||
| return empty; | |||||
| int start = 0; | |||||
| while ((text + start).isWhitespace()) | |||||
| ++start; | |||||
| while (end > start) | |||||
| { | |||||
| if (! (--end).isWhitespace()) | |||||
| { | |||||
| ++end; | |||||
| break; | |||||
| } | |||||
| } | |||||
| const int len = length(); | |||||
| int end = len - 1; | |||||
| return end; | |||||
| } | |||||
| while ((end >= start) && (text + end).isWhitespace()) | |||||
| --end; | |||||
| const String String::trim() const | |||||
| { | |||||
| if (isNotEmpty()) | |||||
| { | |||||
| CharPointerType start (text.findEndOfWhitespace()); | |||||
| ++end; | |||||
| const CharPointerType end (start.findTerminatingNull()); | |||||
| CharPointerType trimmedEnd (findTrimmedEnd (start, end)); | |||||
| if (end <= start) | |||||
| return empty; | |||||
| else if (start > 0 || end < len) | |||||
| return String (text + start, end - start); | |||||
| if (trimmedEnd <= start) | |||||
| return empty; | |||||
| else if (text < start || trimmedEnd < end) | |||||
| return String (start, trimmedEnd); | |||||
| } | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| const String String::trimStart() const | const String String::trimStart() const | ||||
| { | { | ||||
| if (isEmpty()) | |||||
| return empty; | |||||
| CharPointerType t (text.findEndOfWhitespace()); | |||||
| if (isNotEmpty()) | |||||
| { | |||||
| const CharPointerType t (text.findEndOfWhitespace()); | |||||
| if (t == text) | |||||
| return *this; | |||||
| if (t != text) | |||||
| return String (t); | |||||
| } | |||||
| return String (t); | |||||
| return *this; | |||||
| } | } | ||||
| const String String::trimEnd() const | const String String::trimEnd() const | ||||
| { | { | ||||
| if (isEmpty()) | |||||
| return empty; | |||||
| CharPointerType endT (text); | |||||
| endT = endT.findTerminatingNull() - 1; | |||||
| if (isNotEmpty()) | |||||
| { | |||||
| const CharPointerType end (text.findTerminatingNull()); | |||||
| CharPointerType trimmedEnd (findTrimmedEnd (text, end)); | |||||
| while ((endT.getAddress() >= text) && endT.isWhitespace()) | |||||
| --endT; | |||||
| if (trimmedEnd < end) | |||||
| return String (text, trimmedEnd); | |||||
| } | |||||
| return String (text, 1 + (int) (endT.getAddress() - text)); | |||||
| return *this; | |||||
| } | } | ||||
| const String String::trimCharactersAtStart (const String& charactersToTrim) const | const String String::trimCharactersAtStart (const String& charactersToTrim) const | ||||
| @@ -1667,20 +1656,25 @@ const String String::trimCharactersAtStart (const String& charactersToTrim) cons | |||||
| const String String::trimCharactersAtEnd (const String& charactersToTrim) const | const String String::trimCharactersAtEnd (const String& charactersToTrim) const | ||||
| { | { | ||||
| if (isEmpty()) | |||||
| return empty; | |||||
| if (isNotEmpty()) | |||||
| { | |||||
| const CharPointerType end (text.findTerminatingNull()); | |||||
| CharPointerType trimmedEnd (end); | |||||
| const int len = length(); | |||||
| const juce_wchar* endT = text + (len - 1); | |||||
| int numToRemove = 0; | |||||
| while (trimmedEnd > text) | |||||
| { | |||||
| if (! charactersToTrim.containsChar (*--trimmedEnd)) | |||||
| { | |||||
| ++trimmedEnd; | |||||
| break; | |||||
| } | |||||
| } | |||||
| while (numToRemove < len && charactersToTrim.containsChar (*endT)) | |||||
| { | |||||
| ++numToRemove; | |||||
| --endT; | |||||
| if (trimmedEnd < end) | |||||
| return String (text, trimmedEnd); | |||||
| } | } | ||||
| return numToRemove > 0 ? String (text, len - numToRemove) : *this; | |||||
| return *this; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -1734,33 +1728,32 @@ const String String::removeCharacters (const String& charactersToRemove) const | |||||
| const String String::initialSectionContainingOnly (const String& permittedCharacters) const | const String String::initialSectionContainingOnly (const String& permittedCharacters) const | ||||
| { | { | ||||
| int i = 0; | |||||
| CharPointerType t (text); | |||||
| for (;;) | |||||
| while (! t.isEmpty()) | |||||
| { | { | ||||
| if (! permittedCharacters.containsChar (text[i])) | |||||
| break; | |||||
| if (! permittedCharacters.containsChar (*t)) | |||||
| return String (text, t); | |||||
| ++i; | |||||
| ++t; | |||||
| } | } | ||||
| return substring (0, i); | |||||
| return *this; | |||||
| } | } | ||||
| const String String::initialSectionNotContaining (const String& charactersToStopAt) const | const String String::initialSectionNotContaining (const String& charactersToStopAt) const | ||||
| { | { | ||||
| const juce_wchar* const t = text; | |||||
| int i = 0; | |||||
| CharPointerType t (text); | |||||
| while (t[i] != 0) | |||||
| while (! t.isEmpty()) | |||||
| { | { | ||||
| if (charactersToStopAt.containsChar (t[i])) | |||||
| return String (text, i); | |||||
| if (charactersToStopAt.containsChar (*t)) | |||||
| return String (text, t); | |||||
| ++i; | |||||
| ++t; | |||||
| } | } | ||||
| return empty; | |||||
| return *this; | |||||
| } | } | ||||
| bool String::containsOnly (const String& chars) const throw() | bool String::containsOnly (const String& chars) const throw() | ||||
| @@ -1776,10 +1769,10 @@ bool String::containsOnly (const String& chars) const throw() | |||||
| bool String::containsAnyOf (const String& chars) const throw() | bool String::containsAnyOf (const String& chars) const throw() | ||||
| { | { | ||||
| const juce_wchar* t = text; | |||||
| CharPointerType t (text); | |||||
| while (*t != 0) | |||||
| if (chars.containsChar (*t++)) | |||||
| while (! t.isEmpty()) | |||||
| if (chars.containsChar (t.getAndAdvance())) | |||||
| return true; | return true; | ||||
| return false; | return false; | ||||
| @@ -1892,40 +1885,50 @@ double String::getDoubleValue() const throw() | |||||
| static const char* const hexDigits = "0123456789abcdef"; | static const char* const hexDigits = "0123456789abcdef"; | ||||
| const String String::toHexString (const int number) | |||||
| template <typename Type> | |||||
| struct HexConverter | |||||
| { | { | ||||
| juce_wchar buffer[32]; | |||||
| juce_wchar* const end = buffer + 32; | |||||
| juce_wchar* t = end; | |||||
| *--t = 0; | |||||
| unsigned int v = (unsigned int) number; | |||||
| do | |||||
| static const String hexToString (Type v) | |||||
| { | { | ||||
| *--t = (juce_wchar) hexDigits [v & 15]; | |||||
| v >>= 4; | |||||
| juce_wchar buffer[32]; | |||||
| juce_wchar* const end = buffer + 32; | |||||
| juce_wchar* t = end; | |||||
| *--t = 0; | |||||
| } while (v != 0); | |||||
| do | |||||
| { | |||||
| *--t = (juce_wchar) hexDigits [(int) (v & 15)]; | |||||
| v >>= 4; | |||||
| return String (t, (int) (((char*) end) - (char*) t) - 1); | |||||
| } | |||||
| } while (v != 0); | |||||
| const String String::toHexString (const int64 number) | |||||
| { | |||||
| juce_wchar buffer[32]; | |||||
| juce_wchar* const end = buffer + 32; | |||||
| juce_wchar* t = end; | |||||
| *--t = 0; | |||||
| uint64 v = (uint64) number; | |||||
| return String (t, (int) (end - t) - 1); | |||||
| } | |||||
| do | |||||
| static Type stringToHex (String::CharPointerType t) throw() | |||||
| { | { | ||||
| *--t = (juce_wchar) hexDigits [(int) (v & 15)]; | |||||
| v >>= 4; | |||||
| Type result = 0; | |||||
| while (! t.isEmpty()) | |||||
| { | |||||
| const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); | |||||
| if (hexValue >= 0) | |||||
| result = (result << 4) | hexValue; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| }; | |||||
| } while (v != 0); | |||||
| const String String::toHexString (const int number) | |||||
| { | |||||
| return HexConverter <unsigned int>::hexToString ((unsigned int) number); | |||||
| } | |||||
| return String (t, (int) (((char*) end) - (char*) t)); | |||||
| const String String::toHexString (const int64 number) | |||||
| { | |||||
| return HexConverter <uint64>::hexToString ((uint64) number); | |||||
| } | } | ||||
| const String String::toHexString (const short number) | const String String::toHexString (const short number) | ||||
| @@ -1962,34 +1965,12 @@ const String String::toHexString (const unsigned char* data, const int size, con | |||||
| int String::getHexValue32() const throw() | int String::getHexValue32() const throw() | ||||
| { | { | ||||
| int result = 0; | |||||
| CharPointerType t (text); | |||||
| while (! t.isEmpty()) | |||||
| { | |||||
| const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); | |||||
| if (hexValue >= 0) | |||||
| result = (result << 4) | hexValue; | |||||
| } | |||||
| return result; | |||||
| return HexConverter <int>::stringToHex (text); | |||||
| } | } | ||||
| int64 String::getHexValue64() const throw() | int64 String::getHexValue64() const throw() | ||||
| { | { | ||||
| int64 result = 0; | |||||
| CharPointerType t (text); | |||||
| while (! t.isEmpty()) | |||||
| { | |||||
| const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); | |||||
| if (hexValue >= 0) | |||||
| result = (result << 4) | hexValue; | |||||
| } | |||||
| return result; | |||||
| return HexConverter <int64>::stringToHex (text); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -2005,8 +1986,10 @@ const String String::createStringFromData (const void* const data_, const int si | |||||
| { | { | ||||
| return charToString ((char) data[0]); | return charToString ((char) data[0]); | ||||
| } | } | ||||
| else if ((data[0] == (uint8) CharPointer_UTF16::byteOrderMarkBE1 && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkBE2) | |||||
| || (data[0] == (uint8) CharPointer_UTF16::byteOrderMarkLE1 && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkLE1)) | |||||
| else if ((data[0] == (uint8) CharPointer_UTF16::byteOrderMarkBE1 | |||||
| && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkBE2) | |||||
| || (data[0] == (uint8) CharPointer_UTF16::byteOrderMarkLE1 | |||||
| && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkLE1)) | |||||
| { | { | ||||
| const bool bigEndian = (data[0] == (uint8) CharPointer_UTF16::byteOrderMarkBE1); | const bool bigEndian = (data[0] == (uint8) CharPointer_UTF16::byteOrderMarkBE1); | ||||
| const int numChars = size / 2 - 1; | const int numChars = size / 2 - 1; | ||||
| @@ -2454,7 +2437,9 @@ public: | |||||
| expect (s5.removeCharacters ("1wordxya") == " 2 3"); | expect (s5.removeCharacters ("1wordxya") == " 2 3"); | ||||
| expectEquals (s5.removeCharacters (String::empty), s5); | expectEquals (s5.removeCharacters (String::empty), s5); | ||||
| expect (s5.initialSectionContainingOnly ("word") == L"word"); | expect (s5.initialSectionContainingOnly ("word") == L"word"); | ||||
| expect (String ("word").initialSectionContainingOnly ("word") == L"word"); | |||||
| expectEquals (s5.initialSectionNotContaining (String ("xyz ")), String ("word")); | expectEquals (s5.initialSectionNotContaining (String ("xyz ")), String ("word")); | ||||
| expectEquals (s5.initialSectionNotContaining (String (";[:'/")), s5); | |||||
| expect (! s5.isQuotedString()); | expect (! s5.isQuotedString()); | ||||
| expect (s5.quoted().isQuotedString()); | expect (s5.quoted().isQuotedString()); | ||||
| expect (! s5.quoted().unquoted().isQuotedString()); | expect (! s5.quoted().unquoted().isQuotedString()); | ||||
| @@ -123,6 +123,9 @@ public: | |||||
| /** Creates a string from a UTF-32 character string */ | /** Creates a string from a UTF-32 character string */ | ||||
| String (const CharPointer_UTF32& text, size_t maxChars); | String (const CharPointer_UTF32& text, size_t maxChars); | ||||
| /** Creates a string from a UTF-32 character string */ | |||||
| String (const CharPointer_UTF32& start, const CharPointer_UTF32& end); | |||||
| /** Creates a string from an ASCII character string */ | /** Creates a string from an ASCII character string */ | ||||
| String (const CharPointer_ASCII& text); | String (const CharPointer_ASCII& text); | ||||
| @@ -772,7 +775,8 @@ public: | |||||
| /** Returns a section from the start of the string that only contains a certain set of characters. | /** Returns a section from the start of the string that only contains a certain set of characters. | ||||
| This returns the leftmost section of the string, up to (and not including) the | This returns the leftmost section of the string, up to (and not including) the | ||||
| first character that occurs in the string passed in. | |||||
| first character that occurs in the string passed in. (If none of the specified | |||||
| characters are found in the string, the return value will just be the original string). | |||||
| */ | */ | ||||
| const String initialSectionNotContaining (const String& charactersToStopAt) const; | const String initialSectionNotContaining (const String& charactersToStopAt) const; | ||||