Refactor GetStrArraySeparatedByChar, replaced by Split

This commit is contained in:
jief666 2020-08-13 11:21:45 +03:00
parent 59d8cbad7f
commit 052732eba0
3 changed files with 62 additions and 227 deletions

View File

@ -1368,151 +1368,34 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
BOOLEAN BOOLEAN
IsPatchEnabled (const XString8& MatchOSEntry, const XString8& CurrOS) IsPatchEnabled (const XString8& MatchOSEntry, const XString8& CurrOS)
{ {
INTN i;
BOOLEAN ret = FALSE; BOOLEAN ret = FALSE;
struct MatchOSes *mos; // = (__typeof__(mos))AllocatePool(sizeof(struct MatchOSes));
if (MatchOSEntry.isEmpty() || CurrOS.isEmpty()) { if (MatchOSEntry.isEmpty() || CurrOS.isEmpty()) {
return TRUE; //undefined matched corresponds to old behavior return TRUE; //undefined matched corresponds to old behavior
} }
mos = GetStrArraySeparatedByChar(MatchOSEntry.c_str(), ','); XString8Array mos = Split<XString8Array>(MatchOSEntry, ","_XS8).trimEachString();
if (!mos) {
return TRUE; //memory fails -> anyway the patch enabled
}
TrimMatchOSArray(mos); if ( mos[0] == "All"_XS8) {
if (AsciiStrStr(mos->array[0], "All") != NULL) {
return TRUE; return TRUE;
} }
for (i = 0; i < mos->count; ++i) { for (size_t i = 0; i < mos.size(); ++i) {
// dot represent MatchOS // dot represent MatchOS
if ( if (
((AsciiStrStr(mos->array[i], ".") != NULL) && IsOSValid(mos->array[i], CurrOS.c_str())) || // MatchOS ( mos[i].contains("."_XS8) && IsOSValid(mos[i], CurrOS)) || // MatchOS
(AsciiStrStr(mos->array[i], CurrOS.c_str()) != NULL) // MatchBuild ( mos[i].contains(CurrOS) ) // MatchBuild
) { ) {
//DBG("\nthis patch will activated for OS %ls!\n", mos->array[i]); //DBG("\nthis patch will activated for OS %ls!\n", mos->array[i]);
ret = TRUE; ret = TRUE;
break; break;
} }
} }
deallocMatchOSes(mos);
return ret; return ret;
} }
struct
MatchOSes *GetStrArraySeparatedByChar(const CHAR8 *str, CHAR8 sep)
{
struct MatchOSes *mo;
INTN len = 0, i = 0, inc = 1, newLen = 0;
// CHAR8 *comp = NULL; //unused
CHAR8 doubleSep[2];
mo = (__typeof__(mo))AllocatePool(sizeof(struct MatchOSes)); BOOLEAN IsOSValid(const XString8& MatchOS, const XString8& CurrOS)
if (!mo) {
return NULL;
}
mo->count = countOccurrences( str, sep ) + 1;
// DBG("found %d %c in %ls\n", mo->count, sep, str);
len = (INTN)AsciiStrLen(str);
doubleSep[0] = sep; doubleSep[1] = sep;
if(AsciiStrStr(str, doubleSep) || !len || str[0] == sep || str[len -1] == sep) {
mo->count = 0;
mo->array[0] = NULL;
// DBG("emtpy string\n");
return mo;
}
if (mo->count > 1) {
//INTN indexes[mo->count + 1];
INTN *indexes = (INTN *) AllocatePool(mo->count + 1);
for (i = 0; i < len; ++i) {
CHAR8 c = str[i];
if (c == sep) {
indexes[inc]=i;
// DBG("index %d = %d\n", inc, i);
inc++;
}
}
// manually add first index
indexes[0] = 0;
// manually add last index
indexes[mo->count] = len;
for (i = 0; i < mo->count; ++i) {
INTN startLocation, endLocation;
mo->array[i] = 0;
if (i == 0) {
startLocation = indexes[0];
endLocation = indexes[1] - 1;
} else if (i == mo->count - 1) { // never reach the end of the array
startLocation = indexes[i] + 1;
endLocation = len;
} else {
startLocation = indexes[i] + 1;
endLocation = indexes[i + 1] - 1;
}
// DBG("start %d, end %d\n", startLocation, endLocation);
newLen = (endLocation - startLocation) + 2;
/* comp = (CHAR8 *) AllocatePool(newLen);
AsciiStrnCpy(comp, str + startLocation, newLen);
comp[newLen] = '\0'; */
mo->array[i] = (__typeof_am__(mo->array[i]))AllocateCopyPool(newLen, str + startLocation);
mo->array[i][newLen - 1] = '\0';
}
FreePool(indexes);
}
else {
// DBG("str contains only one component and it is our string %ls!\n", str);
mo->array[0] = (__typeof_am__(mo->array[0]))AllocateCopyPool(AsciiStrLen(str)+1, str);
}
return mo;
}
CHAR8*
TrimString(CHAR8* String)
{
CHAR8 *TempString, *End, *TrimmedString;
if (!String) {
return NULL;
}
TempString = String;
for ( ; *TempString == ' '; TempString++) {
}
End = TempString + AsciiStrLen(TempString) - 1;
for ( ; (End > TempString) && (*End == ' '); End--) {
}
*(End + 1) = '\0';
TrimmedString = (__typeof__(TrimmedString))AllocateCopyPool(AsciiStrSize(TempString), TempString);
FreePool(String);
return TrimmedString;
}
VOID
TrimMatchOSArray(struct MatchOSes *s)
{
INTN i;
if (!s) {
return;
}
for (i = 0; i < s->count; i++) {
s->array[i] = TrimString(s->array[i]);
}
}
BOOLEAN IsOSValid(const CHAR8 *MatchOS, const CHAR8 *CurrOS)
{ {
/* example for valid matches are: /* example for valid matches are:
10.7, only 10.7 (10.7.1 will be skipped) 10.7, only 10.7 (10.7.1 will be skipped)
@ -1521,76 +1404,46 @@ BOOLEAN IsOSValid(const CHAR8 *MatchOS, const CHAR8 *CurrOS)
*/ */
BOOLEAN ret = FALSE; BOOLEAN ret = FALSE;
struct MatchOSes *osToc;
struct MatchOSes *currOStoc;
if (!MatchOS || !CurrOS) { if (MatchOS.isEmpty() || CurrOS.isEmpty()) {
return TRUE; //undefined matched corresponds to old behavior return TRUE; //undefined matched corresponds to old behavior
} }
osToc = GetStrArraySeparatedByChar(MatchOS, '.'); // osToc = GetStrArraySeparatedByChar(MatchOS, '.');
currOStoc = GetStrArraySeparatedByChar(CurrOS, '.'); XString8Array osToc = Split<XString8Array>(MatchOS, "."_XS8).trimEachString();
XString8Array currOStoc = Split<XString8Array>(CurrOS, "."_XS8).trimEachString();
if (osToc->count == 2) { if (osToc.size() == 2) {
if (currOStoc->count == 2) { if (currOStoc.size() == 2) {
if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0 if ( osToc[0] == currOStoc[0] && osToc[1] == currOStoc[1]) {
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0) {
ret = TRUE; ret = TRUE;
} }
} }
} else if (osToc->count == 3) { } else if (osToc.size() == 3) {
if (currOStoc->count == 3) { if (currOStoc.size() == 3) {
if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0 if ( osToc[0] == currOStoc[0]
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0 && osToc[1] == currOStoc[1]
&& AsciiStrCmp(osToc->array[2], currOStoc->array[2]) == 0) { && osToc[2] == currOStoc[2]) {
ret = TRUE; ret = TRUE;
} else if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0 } else if ( osToc[0] == currOStoc[0]
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0 && osToc[1] == currOStoc[1]
&& (AsciiStrCmp(osToc->array[2], "x") == 0 || AsciiStrCmp(osToc->array[2], "X") == 0)) { && osToc[2].equalIC("x") ) {
ret = TRUE; ret = TRUE;
} }
} else if (currOStoc->count == 2) { } else if (currOStoc.size() == 2) {
if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0 if ( osToc[0] == currOStoc[0]
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0) { && osToc[1] == currOStoc[1] ) {
ret = TRUE; ret = TRUE;
} else if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0 } else if ( osToc[0] == currOStoc[0]
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0 && osToc[1] == currOStoc[1]
&& (AsciiStrCmp(osToc->array[2], "x") == 0 || AsciiStrCmp(osToc->array[2], "X") == 0)) { && osToc[2].equalIC("x") == 0 ) {
ret = TRUE; ret = TRUE;
} }
} }
} }
deallocMatchOSes(osToc);
deallocMatchOSes(currOStoc);
return ret; return ret;
} }
INTN countOccurrences( const CHAR8 *s, CHAR8 c )
{
return *s == '\0'
? 0
: countOccurrences( s + 1, c ) + (*s == c);
}
VOID deallocMatchOSes(struct MatchOSes *s)
{
INTN i;
if (!s) {
return;
}
for (i = 0; i < s->count; i++) {
if (s->array[i]) {
FreePool(s->array[i]);
}
}
FreePool(s);
}
// End of MatchOS
UINT8 CheckVolumeType(UINT8 VolumeType, TagPtr Prop) UINT8 CheckVolumeType(UINT8 VolumeType, TagPtr Prop)
{ {
UINT8 VolumeTypeTmp = VolumeType; UINT8 VolumeTypeTmp = VolumeType;

View File

@ -922,30 +922,7 @@ BOOLEAN IsPatchEnabled(const XString8& MatchOSEntry, const XString8& CurrOS);
/** return true if a given os contains '.' as separator, /** return true if a given os contains '.' as separator,
and then match components of the current booted OS. Also allow 10.10.x format meaning all revisions and then match components of the current booted OS. Also allow 10.10.x format meaning all revisions
of the 10.10 OS */ of the 10.10 OS */
BOOLEAN IsOSValid(const CHAR8 *MatchOS, const CHAR8 *CurrOS); BOOLEAN IsOSValid(const XString8& MatchOS, const XString8& CurrOS);
// Micky1979: Next five functions (+ needed struct) are to split a string like "10.10.5,10.7,10.11.6,10.8.x"
// in their components separated by comma (in this case)
struct MatchOSes {
INTN count;
CHAR8* array[100];
};
/** return MatchOSes struct (count+array) with the components of str that contains the given char sep as separator. */
struct
MatchOSes *GetStrArraySeparatedByChar(const CHAR8 *str, CHAR8 sep);
/** trim spaces in MatchOSes struct array */
VOID
TrimMatchOSArray(struct MatchOSes *s);
/** free MatchOSes struct and its array. */
VOID deallocMatchOSes(struct MatchOSes *s);
/** count occurrences of a given char in a char* string. */
INTN
countOccurrences(const CHAR8 *s, CHAR8 c);
//get default boot //get default boot

View File

@ -19,46 +19,42 @@
template<typename T, typename Tdummy=void> template<typename T, typename Tdummy=void>
struct _xstringarray__char_type; struct _xstringarray__char_type;
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___String(T))>
{
// typedef const char* type;
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
template<typename T> template<typename T>
struct _xstringarray__char_type<T*, enable_if_t(is_char(T))> struct _xstringarray__char_type<T*, enable_if_t(is_char(T))>
{ {
typedef const T* type;
static const T* getCharPtr(T* t) { return t; } static const T* getCharPtr(T* t) { return t; }
}; };
// //
//template<typename T> //template<typename T>
//struct _xstringarray__char_type<const T*, enable_if_t(is_char(T))> //struct _xstringarray__char_type<const T*, enable_if_t(is_char(T))>
//{ //{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; } // static const T* getCharPtr(const T* t) { return t; }
//}; //};
// //
//template<typename T> //template<typename T>
//struct _xstringarray__char_type<const T[]> //struct _xstringarray__char_type<const T[]>
//{ //{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; } // static const T* getCharPtr(const T* t) { return t; }
//}; //};
// //
//template<typename T, size_t _Np> //template<typename T, size_t _Np>
//struct _xstringarray__char_type<const T[_Np]> //struct _xstringarray__char_type<const T[_Np]>
//{ //{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; } // static const T* getCharPtr(const T* t) { return t; }
//}; //};
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___String(T))>
{
typedef const char* type;
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
//#define XStringArraySuper XObjArray<XStringClass>
#define XStringArraySuper XObjArray<XStringClass> template<class XStringClass_, class XStringArrayClass>
template<class XStringClass_>
class XStringArray_/* : public XStringArraySuper*/ class XStringArray_/* : public XStringArraySuper*/
{ {
protected: protected:
@ -76,8 +72,10 @@ class XStringArray_/* : public XStringArraySuper*/
// #define enable_if _xtools_enable_if_t // #define enable_if _xtools_enable_if_t
/* [] */ /* [] */
template<typename IntegralType, enable_if(is_integral(IntegralType))> template<typename IntegralType, enable_if(is_integral(IntegralType))>
const XStringClass& operator [](IntegralType i) const { return array[i]; } const XStringClass& operator [](IntegralType i) const { return array[i]; }
template<typename IntegralType, enable_if(is_integral(IntegralType))>
XStringClass& operator [](IntegralType i) { return array[i]; }
/* ElementAt */ /* ElementAt */
template<typename IntegralType, enable_if(is_integral(IntegralType))> template<typename IntegralType, enable_if(is_integral(IntegralType))>
const XStringClass& elementAt(IntegralType i) const { return array[i]; } const XStringClass& elementAt(IntegralType i) const { return array[i]; }
@ -196,7 +194,7 @@ class XStringArray_/* : public XStringArraySuper*/
// Add // Add
template<typename CharType> template<typename CharType>
void AddStrings(const CharType* Val1, ...) void AddStrings(const CharType* Val1, ...)
{ {
va_list va; va_list va;
const wchar_t *p; const wchar_t *p;
@ -204,14 +202,14 @@ class XStringArray_/* : public XStringArraySuper*/
{ {
XStringClass* newS = new XStringClass; XStringClass* newS = new XStringClass;
newS->takeValueFrom(Val1); newS->takeValueFrom(Val1);
XStringArraySuper::AddReference(newS, true); AddReference(newS, true);
} }
va_start(va, Val1); va_start(va, Val1);
p = VA_ARG(va, const CharType*); p = VA_ARG(va, const CharType*);
while ( p != nullptr ) { while ( p != nullptr ) {
XStringClass* newS = new XStringClass; XStringClass* newS = new XStringClass;
newS->takeValueFrom(Val1); newS->takeValueFrom(Val1);
XStringArraySuper::AddReference(newS, true); AddReference(newS, true);
p = VA_ARG(va, const CharType*); p = VA_ARG(va, const CharType*);
} }
va_end(va); va_end(va);
@ -228,13 +226,13 @@ class XStringArray_/* : public XStringArraySuper*/
array.AddReference(xstr, true); array.AddReference(xstr, true);
} }
// void Add(const XStringClass &aString) { array.AddCopy(aString); } template<typename XStringClass1, enable_if(is___String(XStringClass1))>
template<typename XStringClass1, enable_if(is___String(XStringClass1))> void Add(const XStringClass1 &aString) { Add(aString.s()); }
void Add(const XStringClass1 &aString) { Add(aString.s()); }
void AddReference(XStringClass *newElement, bool FreeIt) { array.AddReference(newElement, FreeIt); } void AddReference(XStringClass *newElement, bool FreeIt) { array.AddReference(newElement, FreeIt); }
template<class OtherXStringClass>
void import(const XStringArray_<OtherXStringClass> &aStrings) template<class OtherXStringClass, class OtherXStringArrayClass>
void import(const XStringArray_<OtherXStringClass, OtherXStringArrayClass> &aStrings)
{ {
size_t i; size_t i;
@ -283,25 +281,32 @@ class XStringArray_/* : public XStringArraySuper*/
} while ( i > 0 ); } while ( i > 0 );
} }
} }
XStringArrayClass trimEachString()
{
for ( size_t i=0 ; i<array.size() ; i+=1 ) {
array.ElementAt(i).trim();
}
return *((XStringArrayClass*)this);
}
}; };
class XString8Array : public XStringArray_<XString8> class XString8Array : public XStringArray_<XString8, XString8Array>
{ {
}; };
extern const XString8Array NullXString8Array; extern const XString8Array NullXString8Array;
class XString16Array : public XStringArray_<XString16> class XString16Array : public XStringArray_<XString16, XString16Array>
{ {
}; };
extern const XString16Array NullXString16Array; extern const XString16Array NullXString16Array;
class XString32Array : public XStringArray_<XString32> class XString32Array : public XStringArray_<XString32, XString32Array>
{ {
}; };
extern const XString32Array NullXString32Array; extern const XString32Array NullXString32Array;
class XStringWArray : public XStringArray_<XStringW> class XStringWArray : public XStringArray_<XStringW, XStringWArray>
{ {
}; };
extern const XStringWArray NullXStringWArray; extern const XStringWArray NullXStringWArray;
@ -320,8 +325,8 @@ extern const XStringWArray NullXStringWArray;
//template<class XStringArrayClass, typename CharType1, typename CharType2, enable_if(is_char(CharType1) && is_char(CharType2))> //template<class XStringArrayClass, typename CharType1, typename CharType2, enable_if(is_char(CharType1) && is_char(CharType2))>
template<class XStringArrayClass, typename Type1, typename Type2, template<class XStringArrayClass, typename Type1, typename Type2,
enable_if( enable_if(
( is_char_ptr(Type1) || is___String(Type1) ) && ( is_char_ptr(Type1) || is___String(Type1) || is___LString(Type1) ) &&
( is_char_ptr(Type2) || is___String(Type2) ) ( is_char_ptr(Type2) || is___String(Type2) || is___LString(Type2) )
) )
> >
XStringArrayClass Split(Type1 S, const Type2 Separator) XStringArrayClass Split(Type1 S, const Type2 Separator)