From 2693dbfaca635ae0355ab91ed62bcab63e3cfc3b Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 23 Oct 2019 07:12:49 -0700 Subject: [PATCH] Added String.Split --- BeefySysLib/util/String.cpp | 10 ++ BeefySysLib/util/String.h | 206 +++++++++++++++++++++++++++++++++++- 2 files changed, 215 insertions(+), 1 deletion(-) diff --git a/BeefySysLib/util/String.cpp b/BeefySysLib/util/String.cpp index b3c9dc11..6e0f104f 100644 --- a/BeefySysLib/util/String.cpp +++ b/BeefySysLib/util/String.cpp @@ -109,6 +109,11 @@ void StringView::ToString(StringImpl& str) const str.Append(mPtr, mLength); } +StringSplitEnumerator StringView::Split(char c) +{ + return StringSplitEnumerator(mPtr, mLength, c, 0x7FFFFFFF, false); +} + ////////////////////////////////////////////////////////////////////////// String Beefy::operator+(const StringImpl& lhs, const StringImpl& rhs) @@ -492,6 +497,11 @@ void StringImpl::RemoveToEnd(intptr startIdx) Remove(startIdx, mLength - startIdx); } +void StringImpl::RemoveFromEnd(intptr length) +{ + Remove(mLength - length, length); +} + void StringImpl::Insert(intptr idx, const char* str, intptr length) { BF_ASSERT(idx >= 0); diff --git a/BeefySysLib/util/String.h b/BeefySysLib/util/String.h index ea3923b9..11064aec 100644 --- a/BeefySysLib/util/String.h +++ b/BeefySysLib/util/String.h @@ -2,6 +2,7 @@ #include "BFPlatform.h" #include "Array.h" +#include "SizedArray.h" NS_BF_BEGIN; @@ -10,6 +11,8 @@ class StringT; typedef StringT<16> String; +struct StringSplitEnumerator; + class StringView { public: @@ -99,6 +102,11 @@ public: return strB[mLength] != 0; } + bool IsEmpty() const + { + return mLength == 0; + } + intptr IndexOf(const StringView& subStr, bool ignoreCase = false) const; intptr IndexOf(const StringView& subStr, int32 startIdx) const; intptr IndexOf(const StringView& subStr, int64 startIdx) const; @@ -107,6 +115,22 @@ public: intptr LastIndexOf(char c, intptr startCheck) const; String ToString() const; void ToString(StringImpl& str) const; + void RemoveFromStart(intptr length) + { + BF_ASSERT((uintptr)length <= (uintptr)mLength); + mPtr += length; + mLength -= (int)length; + } + + void RemoveToEnd(int startIdx) + { + RemoveFromEnd(mLength - startIdx); + } + + void RemoveFromEnd(int length) + { + mLength -= length; + } bool Contains(char c) const { @@ -117,6 +141,180 @@ public: { return IndexOf(str) != -1; } + + StringSplitEnumerator Split(char c); +}; + +struct StringSplitEnumerator +{ +public: + typedef std::random_access_iterator_tag iterator_category; + typedef char value_type; + typedef intptr difference_type; + + typedef char* pointer; + typedef char& reference; + +public: + char mSplitChar0; + SizedArray mSplitChars; + const char* mPtr; + int32 mStrLen; + int32 mCurCount; + int32 mMaxCount; + int32 mPos; + int32 mMatchPos; + bool mRemoveEntryEntries; + + StringSplitEnumerator(const char* ptr, int strLength, const char* splitCharsPtr, int splitCharCount, int count, bool removeEmptyEntries) + { + mPtr = ptr; + mStrLen = strLength; + // if (splitChars.Count > 0) + // mSplitChar0 = splitChars[0]; + // else + // mSplitChar0 = '\0'; + mSplitChar0 = splitCharsPtr[0]; + if (splitCharCount > 1) + { + mSplitChars.Insert(0, splitCharsPtr + 1, splitCharCount - 1); + } + + mCurCount = 0; + mMaxCount = (int32)count; + mPos = 0; + mMatchPos = -1; + + MoveNext(); + //mSplitOptions = splitOptions; + } + + StringSplitEnumerator(const char* ptr, int strLength, char splitChar, int count, bool removeEmptyEntries) + { + mPtr = ptr; + mStrLen = strLength; + mSplitChar0 = splitChar; + mCurCount = 0; + mMaxCount = (int32)count; + mPos = 0; + mMatchPos = -1; + //mSplitOptions = splitOptions; + MoveNext(); + } + + + bool MoveNext() + { + if (mCurCount >= mMaxCount) + return false; + + mPos = mMatchPos + 1; + + mCurCount++; + if (mCurCount == mMaxCount) + { + mMatchPos = mStrLen; + if (mPos > mMatchPos) + return false; + if ((mMatchPos == mPos) && (mRemoveEntryEntries)) + return false; + return true; + } + + int endDiff = mStrLen - mMatchPos; + if (endDiff == 0) + return false; + while (true) + { + mMatchPos++; + endDiff--; + bool foundMatch = false; + if (endDiff == 0) + { + foundMatch = true; + } + else + { + char c = mPtr[mMatchPos]; + if (c == mSplitChar0) + { + foundMatch = true; + } + else if (mSplitChars.mSize > 0) + { + for (int i = 1; i < mSplitChars.mSize; i++) + if (c == mSplitChars[i]) + foundMatch = true; + } + } + + if (foundMatch) + { + if ((mMatchPos > mPos + 1) || (!mRemoveEntryEntries)) + return true; + mPos = mMatchPos + 1; + if (mPos >= mStrLen) + return false; + } + } + } + + StringSplitEnumerator& operator++() + { + MoveNext(); + return *this; + } + + StringSplitEnumerator operator++(int) + { + auto prevVal = *this; + MoveNext(); + return prevVal; + } + + bool operator!=(const StringSplitEnumerator& itr) const + { + return + (itr.mPtr != mPtr) || + (itr.mPos != mPos) || + (itr.mMatchPos != mMatchPos); + } + + bool operator==(const StringSplitEnumerator& itr) const + { + return + (itr.mPtr == mPtr) && + (itr.mPos == mPos) && + (itr.mMatchPos == mMatchPos); + } + + StringView operator*() + { + return StringView(mPtr + mPos, mMatchPos - mPos); + } + + StringView operator->() + { + return StringView(mPtr + mPos, mMatchPos - mPos); + } + + bool operator<(const StringSplitEnumerator& val2) + { + return mPtr < val2.mPtr; + } + + StringSplitEnumerator begin() + { + return *this; + } + + StringSplitEnumerator end() + { + StringSplitEnumerator endVal = *this; + endVal.mPos = endVal.mStrLen + 1; + endVal.mMatchPos = endVal.mStrLen; + return endVal; + } }; class StringImpl @@ -675,7 +873,8 @@ public: void Remove(intptr startIdx, intptr length); void Remove(intptr char8Idx); - void RemoveToEnd(intptr startIdx); + void RemoveToEnd(intptr startIdx); + void RemoveFromEnd(intptr length); void Insert(intptr idx, const StringImpl& addString); void Insert(intptr idx, const char* str, intptr len); void Insert(intptr idx, char c); @@ -766,6 +965,11 @@ public: intptr LastIndexOf(char c) const; intptr LastIndexOf(char c, intptr startCheck) const; + StringSplitEnumerator Split(char c) + { + return StringSplitEnumerator(GetPtr(), mLength, c, 0x7FFFFFFF, false); + } + bool Contains(char c) const { return IndexOf(c) != -1;