//************************************************************************************************* //************************************************************************************************* // // STRINGS // //************************************************************************************************* //************************************************************************************************* #if !defined(__XSTRINGARRAY_H__) #define __XSTRINGARRAY_H__ #include #include "XToolsCommon.h" #include "XObjArray.h" #include "XString.h" #define XStringArraySuper XObjArray template class XStringArray_/* : public XStringArraySuper*/ { protected: XObjArray array; public: typedef XStringClass_ XStringClass; XStringArray_() {}; size_t size() const { return array.size(); } void setEmpty() { array.Empty(); } bool isEmpty() const { return this->size() == 0 ; } bool notEmpty() const { return this->size() > 0 ; } // #define enable_if XStringAbstract__enable_if_t /* [] */ template const XStringClass& operator [](IntegralType i) const { return array[i]; } /* ElementAt */ template const XStringClass& elementAt(IntegralType i) const { return array[i]; } template XStringClass& elementAt(IntegralType i) { return array[i]; } // const XStringClass& dbg(size_t i) const { return array[i]; } XStringClass ConcatAll(const XStringClass& Separator = ", "_XS, const XStringClass& Prefix = NullXString, const XStringClass& Suffix = NullXString) const { xsize i; XStringClass s; if ( array.size() > 0 ) { s = Prefix; s += array.ElementAt(0); for ( i=1 ; i bool Equal(const OtherXStringArrayClass &aStrings) const { xsize ui; if ( array.size() != aStrings.size() ) return false; for ( ui=0 ; ui bool operator ==(const OtherXStringArrayClass &aXStrings) const { return Equal(aXStrings); } template bool operator !=(const OtherXStringArrayClass& aXStrings) const { return !Equal(aXStrings); } /* contains */ template bool contains(const CharType* s) const { for ( size_t i=0 ; i bool contains(const OtherXStringClass &S) const { return contains(S.s()); } /* containsIC */ template bool containsIC(const CharType* s) const { for ( size_t i=0 ; i bool containsIC(const OtherXStringClass &S) const { return containsIC(S.s()); } /* ContainsStartWithIC */ template bool containsStartWithIC(const CharType* s) const { for ( size_t i=0 ; i bool containsStartWithIC(const OtherXStringClass &S) const { return ContainsStartWithIC(S.s()); } template bool Same(const OtherXStringArrayClass &aStrings) const { xsize i; for ( i=0 ; isize() ; i+=1 ) { if ( !aStrings.contains(array.ElementAt(i)) ) return false; } for ( i=0 ; i void AddStrings(const CharType* Val1, ...) { va_list va; const wchar_t *p; { XStringClass* newS = new XStringClass; newS->takeValueFrom(Val1); XStringArraySuper::AddReference(newS, true); } va_start(va, Val1); p = VA_ARG(va, const CharType*); while ( p != nullptr ) { XStringClass* newS = new XStringClass; newS->takeValueFrom(Val1); XStringArraySuper::AddReference(newS, true); p = VA_ARG(va, const CharType*); } va_end(va); } void AddNoNull(const XStringClass &aString) { if ( !aString.isEmpty() ) array.AddCopy(aString); } void AddEvenNull(const XStringClass &aString) { array.AddCopy(aString); } template void Add(const CharType* s) { XStringClass* xstr = new XStringClass; xstr->strcpy(s); array.AddReference(xstr, true); } void Add(const XStringClass &aString) { array.AddCopy(aString); } void AddReference(XStringClass *newElement, bool FreeIt) { array.AddReference(newElement, FreeIt); } template void import(const XStringArray_ &aStrings) { xsize i; for ( i=0 ; i 0 ) { size_t i = array.size(); do { i--; if ( array[i] == aString ) { array.RemoveAtIndex(i); break; } } while ( i > 0 ); } } void removeIC(const XStringClass &aString) { if ( array.size() > 0 ) { size_t i = array.size(); do { i--; if ( array[i].equalIC(aString) ) { array.RemoveAtIndex(i); break; } } while ( i > 0 ); } } }; class XStringArray : public XStringArray_ { }; extern const XStringArray NullXStringArray; class XString16Array : public XStringArray_ { }; extern const XString16Array NullXString16Array; class XString32Array : public XStringArray_ { }; extern const XString32Array NullXString32Array; class XStringWArray : public XStringArray_ { }; extern const XStringWArray NullXStringWArray; // //template //XStringArrayClass Split(const XStringClass1& S) //{ // return Split(S, ", "_XS); //}; template XStringArrayClass Split(const CharType1* S, const CharType2* Separator) { XStringArrayClass xsArray; size_t separatorLength = length_of_utf_string(Separator); if ( separatorLength == 0 ) { typename XStringArrayClass::XStringClass* xstr; xstr = new typename XStringArrayClass::XStringClass; xstr->takeValueFrom(S); xsArray.AddReference(xstr, true); return xsArray; } const CharType1* s = S; char32_t char32 = 1; do { while ( XStringAbstract__ncompare(s, Separator, separatorLength, false) == 0 ) { // I have to implement a move_forward_one_char in unicode_conversions, as we don't care about char32 for ( size_t i = 0 ; i < separatorLength ; i++ ) s = get_char32_from_string(s, &char32); } const CharType1* t = s; size_t nb = 0; while ( char32 && XStringAbstract__ncompare(t, Separator, separatorLength, false) != 0 ) { nb++; t = get_char32_from_string(t, &char32); } typename XStringArrayClass::XStringClass* xstr; xstr = new typename XStringArrayClass::XStringClass; xstr->strncpy(s, nb); xsArray.AddReference(xstr, true); // s = get_char32_from_string(t, &char32); s = t; // Consume the separator we found for ( size_t i = 0 ; i < separatorLength ; i++ ) s = get_char32_from_string(s, &char32); } while ( char32 ); return xsArray; // // // // TODO : Allocating temporary strings could be avoided by using low level function from unicode_conversions // typename XStringArrayClass::XStringClass SS; // SS.takeValueFrom(S); // typename XStringArrayClass::XStringClass XSeparator; // SS.takeValueFrom(Separator); // return Split(SS, XSeparator); }; template XStringArrayClass Split(const XStringClass1& S, const XStringClass2& Separator) { return Split(S.s(), Separator.s()); // // XStringArrayClass Ss; // size_t idxB, idxE; // // if ( Separator.length() == 0 ) { // Ss.Add(S); // return Ss; // } // idxB = 0; // idxE = S.indexOf(Separator, idxB); // while ( idxE != MAX_XSIZE ) { // Ss.Add(S.subString(idxB, idxE-idxB)); // idxB = idxE + Separator.length(); // idxE = S.indexOf(Separator, idxB); // } // if ( idxB < S.length() ) Ss.Add(S.subString(idxB, S.length()-idxB)); // return Ss; }; template XStringArrayClass Split(const XStringClass1& S) { return Split(S, ", "_XS); }; #endif