Browse Source

Added int64 type to var class. Internal string clean-ups.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
ef71999349
12 changed files with 347 additions and 264 deletions
  1. +65
    -46
      src/audio/plugins/juce_PluginListComponent.cpp
  2. +2
    -0
      src/audio/plugins/juce_PluginListComponent.h
  3. +61
    -9
      src/containers/juce_Variant.cpp
  4. +7
    -0
      src/containers/juce_Variant.h
  5. +1
    -4
      src/native/mac/juce_mac_Strings.mm
  6. +12
    -10
      src/text/juce_CharPointer_ASCII.h
  7. +12
    -10
      src/text/juce_CharPointer_UTF16.h
  8. +12
    -10
      src/text/juce_CharPointer_UTF32.h
  9. +12
    -10
      src/text/juce_CharPointer_UTF8.h
  10. +12
    -3
      src/text/juce_CharacterFunctions.h
  11. +146
    -161
      src/text/juce_String.cpp
  12. +5
    -1
      src/text/juce_String.h

+ 65
- 46
src/audio/plugins/juce_PluginListComponent.cpp View File

@@ -131,56 +131,38 @@ void PluginListComponent::deleteKeyPressed (int 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();
}
else if (r == 2)
{
break;
case 2:
list.sort (KnownPluginList::sortAlphabetically);
}
else if (r == 3)
{
break;
case 3:
list.sort (KnownPluginList::sortByCategory);
}
else if (r == 4)
{
break;
case 4:
list.sort (KnownPluginList::sortByManufacturer);
}
else if (r == 5)
break;
case 5:
{
const SparseSet <int> selected (listBox.getSelectedRows());
for (int i = list.getNumTypes(); --i >= 0;)
if (selected.contains (i))
list.removeType (i);
break;
}
else if (r == 6)
case 6:
{
const PluginDescription* const desc = list.getType (listBox.getSelectedRow());
@@ -189,22 +171,59 @@ void PluginListComponent::buttonClicked (Button* button)
if (File (desc->fileOrIdentifier).existsAsFile())
File (desc->fileOrIdentifier).getParentDirectory().startAsProcess();
}
break;
}
else if (r == 7)
{
case 7:
for (int i = list.getNumTypes(); --i >= 0;)
{
if (! AudioPluginFormatManager::getInstance()->doesPluginStillExist (*list.getType (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));
}
}


+ 2
- 0
src/audio/plugins/juce_PluginListComponent.h View File

@@ -90,6 +90,8 @@ private:
int typeToScan;
void scanFor (AudioPluginFormat* format);
static void optionsMenuStaticCallback (int result, PluginListComponent*);
void optionsMenuCallback (int result);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent);
};


+ 61
- 9
src/containers/juce_Variant.cpp View File

@@ -31,6 +31,15 @@ BEGIN_JUCE_NAMESPACE
#include "juce_DynamicObject.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
@@ -40,6 +49,7 @@ public:
virtual ~VariantType() {}
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 const String toString (const ValueUnion&) const { return String::empty; }
virtual bool toBool (const ValueUnion&) const { return false; }
@@ -47,6 +57,7 @@ public:
virtual bool isVoid() 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 isDouble() const throw() { return false; }
virtual bool isString() const throw() { return false; }
@@ -79,6 +90,7 @@ public:
static const VariantType_Int instance;
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; }
const String toString (const ValueUnion& data) const { return String (data.intValue); }
bool toBool (const ValueUnion& data) const { return data.intValue != 0; }
@@ -92,11 +104,38 @@ public:
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
output.writeCompressedInt (5);
output.writeByte (1);
output.writeByte (varMarker_Int);
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
{
@@ -105,6 +144,7 @@ public:
static const VariantType_Double instance;
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; }
const String toString (const ValueUnion& data) const { return String (data.doubleValue); }
bool toBool (const ValueUnion& data) const { return data.doubleValue != 0; }
@@ -118,7 +158,7 @@ public:
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
output.writeCompressedInt (9);
output.writeByte (4);
output.writeByte (varMarker_Double);
output.writeDouble (data.doubleValue);
}
};
@@ -131,6 +171,7 @@ public:
static const VariantType_Bool instance;
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; }
const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); }
bool toBool (const ValueUnion& data) const { return data.boolValue; }
@@ -144,7 +185,7 @@ public:
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
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); }
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(); }
const String toString (const ValueUnion& data) const { return *data.stringValue; }
bool toBool (const ValueUnion& data) const { return data.stringValue->getIntValue() != 0
@@ -175,7 +217,7 @@ public:
{
const int len = data.stringValue->getNumBytesAsUTF8() + 1;
output.writeCompressedInt (len + 1);
output.writeByte (5);
output.writeByte (varMarker_String);
HeapBlock<char> temp (len);
data.stringValue->copyToUTF8 (temp, len);
output.write (temp, len);
@@ -235,6 +277,7 @@ public:
//==============================================================================
const var::VariantType_Void var::VariantType_Void::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_Double var::VariantType_Double::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_;
}
var::var (const int64 value_) throw() : type (&VariantType_Int64::instance)
{
value.intValue = value_;
}
var::var (const bool value_) throw() : type (&VariantType_Bool::instance)
{
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::isInt() const throw() { return type->isInt(); }
bool var::isInt64() const throw() { return type->isInt64(); }
bool var::isBool() const throw() { return type->isBool(); }
bool var::isDouble() const throw() { return type->isDouble(); }
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(); }
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 float() const { return (float) 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= (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= (double 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())
{
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;
mo.writeFromInputStream (input, numBytes - 1);


+ 7
- 0
src/containers/juce_Variant.h View File

@@ -63,6 +63,7 @@ public:
var (const var& valueToCopy);
var (int value) throw();
var (int64 value) throw();
var (bool value) throw();
var (double value) throw();
var (const char* value);
@@ -73,6 +74,7 @@ public:
var& operator= (const var& valueToCopy);
var& operator= (int value);
var& operator= (int64 value);
var& operator= (bool value);
var& operator= (double value);
var& operator= (const char* value);
@@ -84,6 +86,7 @@ public:
void swapWith (var& other) throw();
operator int() const;
operator int64() const;
operator bool() const;
operator float() const;
operator double() const;
@@ -93,6 +96,7 @@ public:
bool isVoid() const throw();
bool isInt() const throw();
bool isInt64() const throw();
bool isBool() const throw();
bool isDouble() const throw();
bool isString() const throw();
@@ -152,6 +156,8 @@ private:
friend class VariantType_Void;
class VariantType_Int;
friend class VariantType_Int;
class VariantType_Int64;
friend class VariantType_Int64;
class VariantType_Double;
friend class VariantType_Double;
class VariantType_Float;
@@ -168,6 +174,7 @@ private:
union ValueUnion
{
int intValue;
int64 int64Value;
bool boolValue;
double doubleValue;
String* stringValue;


+ 1
- 4
src/native/mac/juce_mac_Strings.mm View File

@@ -117,10 +117,7 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s)
bytesNeeded, &bytesRead,
&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);


+ 12
- 10
src/text/juce_CharPointer_ASCII.h View File

@@ -64,16 +64,12 @@ public:
}
/** 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. */
inline CharType* getAddress() const throw() { return data; }
@@ -171,6 +167,12 @@ public:
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.
This includes the terminating null character.
*/


+ 12
- 10
src/text/juce_CharPointer_UTF16.h View File

@@ -65,16 +65,12 @@ public:
}
/** 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. */
inline CharType* getAddress() const throw() { return data; }
@@ -203,6 +199,12 @@ public:
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.
This includes the terminating null character.
*/


+ 12
- 10
src/text/juce_CharPointer_UTF32.h View File

@@ -61,16 +61,12 @@ public:
}
/** 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. */
inline CharType* getAddress() const throw() { return data; }
@@ -175,6 +171,12 @@ public:
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.
This includes the terminating null character.
*/


+ 12
- 10
src/text/juce_CharPointer_UTF8.h View File

@@ -60,16 +60,12 @@ public:
}
/** 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. */
inline CharType* getAddress() const throw() { return data; }
@@ -243,6 +239,12 @@ public:
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.
This includes the terminating null character.
*/


+ 12
- 3
src/text/juce_CharacterFunctions.h View File

@@ -272,17 +272,26 @@ public:
//==============================================================================
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;
CharPointerType t (text);
while (len < maxCharsToCount && t.getAndAdvance() != 0)
while (len < maxCharsToCount && text.getAndAdvance() != 0)
++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>
static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) throw()


+ 146
- 161
src/text/juce_String.cpp View File

@@ -100,6 +100,21 @@ public:
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)
{
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)
: 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)
{
String result (Preallocation (1));
result.text[0] = character;
result.text[1] = 0;
CharPointerType t (result.text);
t.write (character);
t.writeNull();
return result;
}
@@ -540,22 +561,22 @@ const juce_wchar String::operator[] (int index) const throw()
int String::hashCode() const throw()
{
const juce_wchar* t = text;
CharPointerType t (text);
int result = 0;
while (*t != (juce_wchar) 0)
result = 31 * result + *t++;
while (! t.isEmpty())
result = 31 * result + t.getAndAdvance();
return result;
}
int64 String::hashCode64() const throw()
{
const juce_wchar* t = text;
CharPointerType t (text);
int64 result = 0;
while (*t != (juce_wchar) 0)
result = 101 * result + *t++;
while (! t.isEmpty())
result = 101 * result + t.getAndAdvance();
return result;
}
@@ -703,7 +724,6 @@ void String::append (const String& textToAppend, size_t maxCharsToTake)
String& String::operator+= (const juce_wchar* const t)
{
appendCharPointer (CharPointer_UTF32 (t));
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()
{
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()
@@ -913,21 +924,8 @@ int String::indexOf (const String& t) const throw()
int String::indexOfChar (const int startIndex,
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,
@@ -1058,18 +1056,7 @@ bool String::contains (const String& other) 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()
@@ -1210,15 +1197,11 @@ const String String::repeatedString (const String& stringToRepeat, int numberOfT
if (numberOfTimesToRepeat <= 0)
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);
while (--numberOfTimesToRepeat >= 0)
{
StringHolder::copyChars (n, stringToRepeat.text, len);
n += len;
}
n.writeAll (stringToRepeat.text);
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;
}
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
{
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
@@ -1667,20 +1656,25 @@ const String String::trimCharactersAtStart (const String& charactersToTrim) cons
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
{
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 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()
@@ -1776,10 +1769,10 @@ bool String::containsOnly (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 false;
@@ -1892,40 +1885,50 @@ double String::getDoubleValue() const throw()
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)
@@ -1962,34 +1965,12 @@ const String String::toHexString (const unsigned char* data, const int size, con
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 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]);
}
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 int numChars = size / 2 - 1;
@@ -2454,7 +2437,9 @@ public:
expect (s5.removeCharacters ("1wordxya") == " 2 3");
expectEquals (s5.removeCharacters (String::empty), s5);
expect (s5.initialSectionContainingOnly ("word") == L"word");
expect (String ("word").initialSectionContainingOnly ("word") == L"word");
expectEquals (s5.initialSectionNotContaining (String ("xyz ")), String ("word"));
expectEquals (s5.initialSectionNotContaining (String (";[:'/")), s5);
expect (! s5.isQuotedString());
expect (s5.quoted().isQuotedString());
expect (! s5.quoted().unquoted().isQuotedString());


+ 5
- 1
src/text/juce_String.h View File

@@ -123,6 +123,9 @@ public:
/** Creates a string from a UTF-32 character string */
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 */
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.
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;


Loading…
Cancel
Save