/* * * Created by jief in 1997. * Copyright (c) 2020 Jief * All rights reserved. * */ #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_() : array() {}; template XStringArray_(const XStringArray_& other) : array() { *this = other; } template XStringArray_& operator = (const XStringArray_& other) { for ( size_t idx = 0 ; idx < other.size() ; ++idx ) { array.AddCopy(other[idx]); } return *this; // return *((XStringArrayClass*)this); } // template // XStringArrayClass& operator =(const XStringArray_& other) { array = other.array; return *((XStringArrayClass*)this); } size_t size() const { return array.size(); } void setEmpty() { array.setEmpty(); } bool isEmpty() const { return this->size() == 0 ; } bool notEmpty() const { return this->size() > 0 ; } // #define enable_if _xtools_enable_if_t /* [] */ template const XStringClass& operator [](IntegralType i) const { return array[i]; } template XStringClass& operator [](IntegralType i) { return array[i]; } /* ElementAt */ template const XStringClass& elementAt(IntegralType i) const { return array[i]; } template XStringClass& elementAt(IntegralType i) { return array[i]; } template XStringClass ConcatAll(const Type1& Separator, const Type2& Prefix, const Type3& Suffix) const { size_t i; remove_const(XStringClass) s; if ( array.size() > 0 ) { s.takeValueFrom(Prefix); s += array.ElementAt(0); for ( i=1 ; i XStringClass ConcatAll(const Type1& Separator) const { return ConcatAll(Separator, "", ""); } template bool Equal(const OtherXStringArrayClass &aStrings) const { size_t 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 { size_t i; for ( i=0 ; isize() ; i+=1 ) { if ( !aStrings.contains(array.ElementAt(i)) ) return false; } for ( i=0 ; i void AddStrings(const CharType* Val1, ...) { XTOOLS_VA_LIST va; const wchar_t *p; { remove_const(XStringClass)* newS = new remove_const(XStringClass); newS->takeValueFrom(Val1); AddReference(newS, true); } XTOOLS_VA_START(va, Val1); p = XTOOLS_VA_ARG(va, const CharType*); while ( p != nullptr ) { remove_const(XStringClass)* newS = new remove_const(XStringClass); newS->takeValueFrom(p); AddReference(newS, true); p = XTOOLS_VA_ARG(va, const CharType*); } XTOOLS_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) { remove_const(XStringClass)* xstr = new remove_const(XStringClass); xstr->strcpy(s); array.AddReference(xstr, true); } template void Add(const XStringClass1 &aString) { Add(aString.s()); } template void insertAtPos(const XStringClass1 &aString, size_t pos) { array.InsertRef(new remove_const(XStringClass1)(aString), pos, true); } template void AddReference(CharType* newElement, bool FreeIt) { if ( FreeIt ) { XStringClass_* s = new XStringClass_(); s->stealValueFrom(newElement); array.AddReference(s, true); }else{ XStringClass_* s = new XStringClass_(); s->takeValueFrom(newElement); array.AddReference(s, true); } } void AddReference(XStringClass* newElement, bool FreeIt) { array.AddReference(newElement, FreeIt); } void insertReferenceAtPos(XStringClass* newElement, size_t pos, bool FreeIt) { array.InsertRef(newElement, pos, FreeIt); } template XStringClass* ExtractFromPos(IntegralType i) { return array.RemoveWithoutFreeingAtIndex(i); } template void import(const XStringArray_ &aStrings) { size_t 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 removeAtPos(size_t pos) { array.RemoveAtIndex(pos); } void removeIC(const XStringClass &aString) { if ( array.size() > 0 ) { size_t i = array.size(); do { i--; if ( array[i].isEqualIC(aString) ) { array.RemoveAtIndex(i); break; } } while ( i > 0 ); } } XStringArrayClass trimEachString() { for ( size_t i=0 ; i { public: using super = XStringArray_; XString8Array() : super() {} template XString8Array(const XStringArray_& other) : super(other) {} // template // XStringArrayClass& operator =(const XStringArray_& other) { array = other.array; return *((XStringArrayClass*)this); } }; extern const XString8Array NullXString8Array; class XString16Array : public XStringArray_ { public: using super = XStringArray_; XString16Array() : super() {} template XString16Array(const XStringArray_& other) : super(other) {} }; extern const XString16Array NullXString16Array; class XString32Array : public XStringArray_ { public: using super = XStringArray_; XString32Array() : super() {} template XString32Array(const XStringArray_& other) : super(other) {} }; extern const XString32Array NullXString32Array; class XStringWArray : public XStringArray_ { public: using super = XStringArray_; XStringWArray() : super() {} template XStringWArray(const XStringArray_& other) : super(other) {} }; extern const XStringWArray NullXStringWArray; class ConstXString8Array : public XStringArray_ { public: using super = XStringArray_; ConstXString8Array() : super() {} template ConstXString8Array(const XStringArray_& other) : super(other) {} }; extern const ConstXString8Array NullConstXString8Array; class ConstXStringWArray : public XStringArray_ { public: using super = XStringArray_; ConstXStringWArray() : super() {} template ConstXStringWArray(const XStringArray_& other) : super(other) {} }; extern const ConstXStringWArray NullConstXStringWArray; // //template //XStringArrayClass Split(const XStringClass1& S) //{ // return Split(S, ", "_XS8); //}; //template template XStringArrayClass Split(Type1 S, const Type2 Separator) { XStringArrayClass xsArray; auto s = _xstringarray__char_type::getCharPtr(S); auto separator = _xstringarray__char_type::getCharPtr(Separator); // typename _xstringarray__char_type::type separator = Separator; 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; } // typename _xstringarray__char_type::type s = S; // 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); } if ( !*s ) return xsArray; auto t = s; // typename _xstringarray__char_type::type t = s; // 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(Type1 S) { return Split(S, ", "); }; // //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, ", "_XS8); //}; #endif