LMMS
Loading...
Searching...
No Matches
StringArray.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the Water library.
5 Copyright (c) 2016 ROLI Ltd.
6 Copyright (C) 2017-2022 Filipe Coelho <falktx@falktx.com>
7
8 Permission is granted to use this software under the terms of the ISC license
9 http://www.isc.org/downloads/software-support-policy/isc-license/
10
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted, provided that the above
13 copyright notice and this permission notice appear in all copies.
14
15 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 OF THIS SOFTWARE.
22
23 ==============================================================================
24*/
25
26#include "StringArray.h"
27
28namespace water {
29
33
35 : strings (other.strings)
36{
37}
38
40{
41 strings.add (firstValue);
42}
43
44StringArray::StringArray (const String* initialStrings, int numberOfStrings)
45{
46 strings.addArray (initialStrings, numberOfStrings);
47}
48
49StringArray::StringArray (const char* const* initialStrings)
50{
51 strings.addNullTerminatedArray (initialStrings);
52}
53
54StringArray::StringArray (const char* const* initialStrings, int numberOfStrings)
55{
56 strings.addArray (initialStrings, numberOfStrings);
57}
58
60{
61 strings = other.strings;
62 return *this;
63}
64
68
69bool StringArray::operator== (const StringArray& other) const noexcept
70{
71 return strings == other.strings;
72}
73
74bool StringArray::operator!= (const StringArray& other) const noexcept
75{
76 return ! operator== (other);
77}
78
79void StringArray::swapWith (StringArray& other) noexcept
80{
81 strings.swapWith (other.strings);
82}
83
85{
86 strings.clear();
87}
88
90{
91 strings.clearQuick();
92}
93
94const String& StringArray::operator[] (const int index) const noexcept
95{
96 if (isPositiveAndBelow (index, strings.size()))
97 return strings.getReference (index);
98
99 static String empty;
100 return empty;
101}
102
103String& StringArray::getReference (const int index) noexcept
104{
105 return strings.getReference (index);
106}
107
108bool StringArray::add (const String& newString)
109{
110 return strings.add (newString);
111}
112
113bool StringArray::insert (const int index, const String& newString)
114{
115 return strings.insert (index, newString);
116}
117
118bool StringArray::addIfNotAlreadyThere (const String& newString, const bool ignoreCase)
119{
120 if (contains (newString, ignoreCase))
121 return false;
122
123 return add (newString);
124}
125
126void StringArray::addArray (const StringArray& otherArray, int startIndex, int numElementsToAdd)
127{
128 if (startIndex < 0)
129 {
131 startIndex = 0;
132 }
133
134 if (numElementsToAdd < 0 || startIndex + numElementsToAdd > otherArray.size())
135 numElementsToAdd = otherArray.size() - startIndex;
136
137 while (--numElementsToAdd >= 0)
138 strings.add (otherArray.strings.getReference (startIndex++));
139}
140
141void StringArray::mergeArray (const StringArray& otherArray, const bool ignoreCase)
142{
143 for (int i = 0; i < otherArray.size(); ++i)
144 addIfNotAlreadyThere (otherArray[i], ignoreCase);
145}
146
147void StringArray::set (const int index, const String& newString)
148{
149 strings.set (index, newString);
150}
151
152bool StringArray::contains (StringRef stringToLookFor, const bool ignoreCase) const
153{
154 return indexOf (stringToLookFor, ignoreCase) >= 0;
155}
156
157int StringArray::indexOf (StringRef stringToLookFor, const bool ignoreCase, int i) const
158{
159 if (i < 0)
160 i = 0;
161
162 const int numElements = size();
163
164 if (ignoreCase)
165 {
166 for (; i < numElements; ++i)
167 if (strings.getReference(i).equalsIgnoreCase (stringToLookFor))
168 return i;
169 }
170 else
171 {
172 for (; i < numElements; ++i)
173 if (stringToLookFor == strings.getReference (i))
174 return i;
175 }
176
177 return -1;
178}
179
180//==============================================================================
181void StringArray::remove (const int index)
182{
183 strings.remove (index);
184}
185
186void StringArray::removeString (StringRef stringToRemove, const bool ignoreCase)
187{
188 if (ignoreCase)
189 {
190 for (int i = size(); --i >= 0;)
191 if (strings.getReference(i).equalsIgnoreCase (stringToRemove))
192 strings.remove (i);
193 }
194 else
195 {
196 for (int i = size(); --i >= 0;)
197 if (stringToRemove == strings.getReference (i))
198 strings.remove (i);
199 }
200}
201
202void StringArray::removeRange (int startIndex, int numberToRemove)
203{
204 strings.removeRange (startIndex, numberToRemove);
205}
206
207//==============================================================================
208void StringArray::removeEmptyStrings (const bool removeWhitespaceStrings)
209{
210 if (removeWhitespaceStrings)
211 {
212 for (int i = size(); --i >= 0;)
213 if (! strings.getReference(i).containsNonWhitespaceChars())
214 strings.remove (i);
215 }
216 else
217 {
218 for (int i = size(); --i >= 0;)
219 if (strings.getReference(i).isEmpty())
220 strings.remove (i);
221 }
222}
223
225{
226 for (int i = size(); --i >= 0;)
227 {
228 String& s = strings.getReference(i);
229 s = s.trim();
230 }
231}
232
233//==============================================================================
235{
236 static int compareElements (String& s1, String& s2) noexcept { return s1.compare (s2); }
237};
238
240{
241 static int compareElements (String& s1, String& s2) noexcept { return s1.compareIgnoreCase (s2); }
242};
243
245{
246 static int compareElements (String& s1, String& s2) noexcept { return s1.compareNatural (s2); }
247};
248
249void StringArray::sort (const bool ignoreCase)
250{
251 if (ignoreCase)
252 {
254 strings.sort (comp);
255 }
256 else
257 {
259 strings.sort (comp);
260 }
261}
262
268
269//==============================================================================
270String StringArray::joinIntoString (StringRef separator, int start, int numberToJoin) const
271{
272 const int last = (numberToJoin < 0) ? size()
273 : jmin (size(), start + numberToJoin);
274
275 if (start < 0)
276 start = 0;
277
278 if (start >= last)
279 return String();
280
281 if (start == last - 1)
282 return strings.getReference (start);
283
284 const size_t separatorBytes = separator.text.sizeInBytes() - sizeof (CharPointer_UTF8::CharType);
285 size_t bytesNeeded = separatorBytes * (size_t) (last - start - 1);
286
287 for (int i = start; i < last; ++i)
288 bytesNeeded += strings.getReference(i).getCharPointer().sizeInBytes() - sizeof (CharPointer_UTF8::CharType);
289
291 result.preallocateBytes (bytesNeeded);
292
293 CharPointer_UTF8 dest (result.getCharPointer());
294
295 while (start < last)
296 {
297 const String& s = strings.getReference (start);
298
299 if (! s.isEmpty())
300 dest.writeAll (s.getCharPointer());
301
303 dest.writeAll (separator.text);
304 }
305
306 dest.writeNull();
307
308 return result;
309}
310
311int StringArray::addTokens (StringRef text, const bool preserveQuotedStrings)
312{
313 return addTokens (text, " \n\r\t", preserveQuotedStrings ? "\"" : "");
314}
315
316int StringArray::addTokens (StringRef text, StringRef breakCharacters, StringRef quoteCharacters)
317{
318 int num = 0;
319
320 if (text.isNotEmpty())
321 {
322 for (CharPointer_UTF8 t (text.text);;)
323 {
325 breakCharacters.text,
326 quoteCharacters.text));
327 strings.add (String (t, tokenEnd));
328 ++num;
329
330 if (tokenEnd.isEmpty())
331 break;
332
333 t = ++tokenEnd;
334 }
335 }
336
337 return num;
338}
339
341{
342 int numLines = 0;
343 CharPointer_UTF8 text (sourceText.text);
344 bool finished = text.isEmpty();
345
346 while (! finished)
347 {
348 for (CharPointer_UTF8 startOfLine (text);;)
349 {
350 const CharPointer_UTF8 endOfLine (text);
351
352 switch (text.getAndAdvance())
353 {
354 case 0: finished = true; break;
355 case '\n': break;
356 case '\r': if (*text == '\n') ++text; break;
357 default: continue;
358 }
359
360 strings.add (String (startOfLine, endOfLine));
361 ++numLines;
362 break;
363 }
364 }
365
366 return numLines;
367}
368
369StringArray StringArray::fromTokens (StringRef stringToTokenise, bool preserveQuotedStrings)
370{
372 s.addTokens (stringToTokenise, preserveQuotedStrings);
373 return s;
374}
375
377 StringRef breakCharacters,
378 StringRef quoteCharacters)
379{
381 s.addTokens (stringToTokenise, breakCharacters, quoteCharacters);
382 return s;
383}
384
386{
388 s.addLines (stringToBreakUp);
389 return s;
390}
391
392//==============================================================================
393void StringArray::removeDuplicates (const bool ignoreCase)
394{
395 for (int i = 0; i < size() - 1; ++i)
396 {
397 const String s (strings.getReference(i));
398
399 for (int nextIndex = i + 1;;)
400 {
401 nextIndex = indexOf (s, ignoreCase, nextIndex);
402
403 if (nextIndex < 0)
404 break;
405
406 strings.remove (nextIndex);
407 }
408 }
409}
410
411void StringArray::appendNumbersToDuplicates (const bool ignoreCase,
412 const bool appendNumberToFirstInstance,
413 CharPointer_UTF8 preNumberString,
414 CharPointer_UTF8 postNumberString)
415{
416 CharPointer_UTF8 defaultPre (" ("), defaultPost (")");
417
418 if (preNumberString.getAddress() == nullptr)
419 preNumberString = defaultPre;
420
421 if (postNumberString.getAddress() == nullptr)
422 postNumberString = defaultPost;
423
424 for (int i = 0; i < size() - 1; ++i)
425 {
426 String& s = strings.getReference(i);
427
428 int nextIndex = indexOf (s, ignoreCase, i + 1);
429
430 if (nextIndex >= 0)
431 {
432 const String original (s);
433
434 int number = 0;
435
436 if (appendNumberToFirstInstance)
437 s = original + String (preNumberString) + String (++number) + String (postNumberString);
438 else
439 ++number;
440
441 while (nextIndex >= 0)
442 {
443 set (nextIndex, (*this)[nextIndex] + String (preNumberString) + String (++number) + String (postNumberString));
444 nextIndex = indexOf (original, ignoreCase, nextIndex + 1);
445 }
446 }
447 }
448}
449
450void StringArray::ensureStorageAllocated (int minNumElements)
451{
452 strings.ensureStorageAllocated (minNumElements);
453}
454
456{
457 strings.minimiseStorageOverheads();
458}
459
460}
#define noexcept
Definition DistrhoDefines.h:72
Definition CharPointer_UTF8.h:45
CharType * getAddress() const noexcept
Definition CharPointer_UTF8.h:80
size_t sizeInBytes() const noexcept
Definition CharPointer_UTF8.h:285
void writeNull() const noexcept
Definition CharPointer_UTF8.h:361
bool isEmpty() const noexcept
Definition CharPointer_UTF8.h:86
void writeAll(const CharPointer src) noexcept
Definition CharPointer_UTF8.h:368
char CharType
Definition CharPointer_UTF8.h:47
static Type findEndOfToken(Type text, const BreakType breakCharacters, const Type quoteCharacters)
Definition CharacterFunctions.h:589
void set(int index, const String &newString)
Definition StringArray.cpp:147
bool operator!=(const StringArray &) const noexcept
Definition StringArray.cpp:74
void clear()
Definition StringArray.cpp:84
bool add(const String &stringToAdd)
Definition StringArray.cpp:108
Array< String > strings
Definition StringArray.h:387
void trim()
Definition StringArray.cpp:224
int size() const noexcept
Definition StringArray.h:97
~StringArray()
Definition StringArray.cpp:65
bool contains(StringRef stringToLookFor, bool ignoreCase=false) const
Definition StringArray.cpp:152
bool insert(int index, const String &stringToAdd)
Definition StringArray.cpp:113
void sortNatural()
Definition StringArray.cpp:263
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Definition StringArray.cpp:369
String joinIntoString(StringRef separatorString, int startIndex=0, int numberOfElements=-1) const
Definition StringArray.cpp:270
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Definition StringArray.cpp:311
bool addIfNotAlreadyThere(const String &stringToAdd, bool ignoreCase=false)
Definition StringArray.cpp:118
void minimiseStorageOverheads()
Definition StringArray.cpp:455
void sort(bool ignoreCase)
Definition StringArray.cpp:249
void removeDuplicates(bool ignoreCase)
Definition StringArray.cpp:393
bool operator==(const StringArray &) const noexcept
Definition StringArray.cpp:69
void clearQuick()
Definition StringArray.cpp:89
static StringArray fromLines(StringRef stringToBreakUp)
Definition StringArray.cpp:385
void ensureStorageAllocated(int minNumElements)
Definition StringArray.cpp:450
const String & operator[](int index) const noexcept
Definition StringArray.cpp:94
String & getReference(int index) noexcept
Definition StringArray.cpp:103
int addLines(StringRef stringToBreakUp)
Definition StringArray.cpp:340
StringArray & operator=(const StringArray &)
Definition StringArray.cpp:59
void remove(int index)
Definition StringArray.cpp:181
void removeEmptyStrings(bool removeWhitespaceStrings=true)
Definition StringArray.cpp:208
void mergeArray(const StringArray &other, bool ignoreCase=false)
Definition StringArray.cpp:141
void appendNumbersToDuplicates(bool ignoreCaseWhenComparing, bool appendNumberToFirstInstance, CharPointer_UTF8 preNumberString=CharPointer_UTF8(nullptr), CharPointer_UTF8 postNumberString=CharPointer_UTF8(nullptr))
Definition StringArray.cpp:411
void swapWith(StringArray &) noexcept
Definition StringArray.cpp:79
void removeRange(int startIndex, int numberToRemove)
Definition StringArray.cpp:202
StringArray() noexcept
Definition StringArray.cpp:30
void removeString(StringRef stringToRemove, bool ignoreCase=false)
Definition StringArray.cpp:186
int indexOf(StringRef stringToLookFor, bool ignoreCase=false, int startIndex=0) const
Definition StringArray.cpp:157
void addArray(const StringArray &other, int startIndex=0, int numElementsToAdd=-1)
Definition StringArray.cpp:126
Definition String.h:48
Definition StringRef.h:67
CharPointer_UTF8 text
Definition StringRef.h:120
struct huft * t
Definition inflate.c:943
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
virtual ASIOError start()=0
#define wassertfalse
static int finished(SordWorld *world, SordModel *sord, int status)
Definition sord_test.c:390
static int JUCE_CDECL comp(const void *a, const void *b)
Definition lsp.c:298
Definition AudioSampleBuffer.h:33
bool operator==(const ReferenceCountedObjectPtr< ReferenceCountedObjectClass > &object1, ReferenceCountedObjectClass *const object2) noexcept
Definition ReferenceCountedObject.h:359
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
bool isPositiveAndBelow(Type valueToTest, Type upperLimit) noexcept
Definition MathsFunctions.h:187
static int compareElements(String &s1, String &s2) noexcept
Definition StringArray.cpp:241
static int compareElements(String &s1, String &s2) noexcept
Definition StringArray.cpp:236
Definition StringArray.cpp:245
static int compareElements(String &s1, String &s2) noexcept
Definition StringArray.cpp:246
const char * text
Definition swell-functions.h:167
int result
Definition process.c:1455