diff --git a/uppsrc/Core/Core.upp b/uppsrc/Core/Core.upp index 70f44fc74..ad00d13a2 100644 --- a/uppsrc/Core/Core.upp +++ b/uppsrc/Core/Core.upp @@ -46,6 +46,7 @@ file heapdbg.cpp optimize_speed, String.h, AString.hpp, + StringFind.cpp, String.cpp optimize_speed, WString.cpp optimize_speed, StrUtil.cpp optimize_speed, diff --git a/uppsrc/Core/String.cpp b/uppsrc/Core/String.cpp index f3cb1316d..7542a711d 100644 --- a/uppsrc/Core/String.cpp +++ b/uppsrc/Core/String.cpp @@ -2,192 +2,6 @@ NAMESPACE_UPP -#ifdef CPU_X86 // Use unaligned access - -inline -bool equal_back_8(const char *a, const char *b, int len) -{ - while(len > 8) { - len -= 8; - if(Peek64le(a + len) != Peek64le(b + len)) - return false; - } - return true; -} - -template // Template parameter to be a constant -int t_find(const char *ptr, int slen, const char *p, int len, int from) -{ - ASSERT(from >= 0 && from <= slen); - int l = slen - len - from; - if(l < 0) - return -1; - const char *s = ptr + from; - const char *e = s + l; - if(len <= 8) { - if(len > 4) { - len -= 4; - int32 p0 = Peek32le(p); - int32 p1 = Peek32le(p + len); - while(s <= e) { - if(Peek32le(s) == p0 && Peek32le(s + len) == p1) - return (int)(s - ptr); - s += step; - } - } - else - if(len == 4) { - int32 p0 = Peek32le(p); - while(s <= e) { - if(Peek32le(s) == p0) - return (int)(s - ptr); - s += step; - } - } - else - if(len == 3) { - int16 p0 = Peek16le(p); - char p1 = p[2]; - while(s <= e) { - if(Peek16le(s) == p0 && s[2] == p1) - return (int)(s - ptr); - s += step; - } - } - else - if(len == 2) { - int16 p0 = Peek16le(p); - while(s <= e) { - if(Peek16le(s) == p0) - return (int)(s - ptr); - s += step; - } - } - else - if(len == 1) { - char p0 = p[0]; - while(s <= e) { - if(*s == p0) - return (int)(s - ptr); - s += step; - } - } - else - return true; - } - else { - int64 p0 = Peek64le(p); - if(len <= 16) { - len -= 8; - int64 p1 = Peek64le(p + len); - while(s <= e) { - if(Peek64le(s) == p0 && Peek64le(s + len) == p1) - return (int)(s - ptr); - s += step; - } - } - else - while(s <= e) { - if(Peek64le(s) == p0 && equal_back_8(s, p, len)) - return (int)(s - ptr); - s += step; - } - } - return -1; -} - -int find(const char *text, int len, const char *needle, int nlen, int from) -{ - return t_find<1>(text, len, needle, nlen, from); -} - -int find(const wchar *text, int len, const wchar *needle, int nlen, int from) -{ - return t_find<2>((const char *)text, 2 * len, (const char *)needle, 2 * nlen, from) / 2; -} - -#else - -template -int t_find(const tchar *ptr, int plen, const tchar *s, int len, int from) -{ - ASSERT(from >= 0 && from <= plen); - int l = plen - len - from; - if(l < 0) - return -1; - if(len == 0) - return from; - const tchar *p = ptr + from; - const tchar *e = p + l; - if(len > 4) { - tchar s0 = s[0]; - tchar s1 = s[1]; - tchar s2 = s[2]; - tchar sl = s[len - 1]; - int l_1 = len - 1; - while(p <= e) { - if(s0 == p[0] && sl == p[l_1] && s1 == p[1] && s2 == p[2] && - svo_memeq(s + 3, p + 3, len - 4)) - return (int)(p - ptr); - p++; - } - } - else - if(len == 4) { - tchar s0 = s[0]; - tchar s1 = s[1]; - tchar s2 = s[2]; - tchar s3 = s[3]; - while(p <= e) { - if(s0 == p[0] && s3 == p[3] && s1 == p[1] && s2 == p[2]) - return (int)(p - ptr); - p++; - } - } - else - if(len == 3) { - tchar s0 = s[0]; - tchar s1 = s[1]; - tchar s2 = s[2]; - while(p <= e) { - if(s0 == p[0] && s2 == p[2] && s1 == p[1]) - return (int)(p - ptr); - p++; - } - } - else - if(len == 2) { - tchar s0 = s[0]; - tchar s1 = s[1]; - while(p <= e) { - if(s0 == p[0] && s1 == p[1]) - return (int)(p - ptr); - p++; - } - } - else { - tchar s0 = s[0]; - while(p <= e) { - if(s0 == *p) - return (int)(p - ptr); - p++; - } - } - return -1; -} - -int find(const char *text, int len, const char *needle, int nlen, int from) -{ - return t_find(text, len, needle, nlen, from); -} - -int find(const wchar *text, int len, const wchar *needle, int nlen, int from) -{ - return t_find(text, len, needle, nlen, from); -} -#endif - - #ifdef _DEBUG void String0::Dsyn() { diff --git a/uppsrc/Core/StringFind.cpp b/uppsrc/Core/StringFind.cpp new file mode 100644 index 000000000..fff9eb948 --- /dev/null +++ b/uppsrc/Core/StringFind.cpp @@ -0,0 +1,210 @@ +#include "Core.h" + +NAMESPACE_UPP + +#ifdef CPU_X86 // Use unaligned access + +#ifdef CPU_64 +inline bool equal_back_8(const char *a, const char *b, int len) +{ + while(len > 8) { + len -= 8; + if(Peek64le(a + len) != Peek64le(b + len)) + return false; + } + return true; +} +#else +inline bool equal_back_4(const char *a, const char *b, int len) +{ + while(len > 4) { + len -= 4; + if(Peek32le(a + len) != Peek32le(b + len)) + return false; + } + return true; +} +#endif + +template // Template parameter to be a constant +int t_find(const char *ptr, int slen, const char *p, int len, int from) +{ + ASSERT(from >= 0 && from <= slen); + int l = slen - len - from; + if(l < 0) + return -1; + const char *s = ptr + from; + const char *e = s + l; + if(len <= 8) { + if(len > 4) { + len -= 4; + int32 p0 = Peek32le(p); + int32 p1 = Peek32le(p + len); + while(s <= e) { + if(Peek32le(s) == p0 && Peek32le(s + len) == p1) + return (int)(s - ptr); + s += step; + } + } + else + if(len == 4) { + int32 p0 = Peek32le(p); + while(s <= e) { + if(Peek32le(s) == p0) + return (int)(s - ptr); + s += step; + } + } + else + if(len == 3) { + int16 p0 = Peek16le(p); + char p1 = p[2]; + while(s <= e) { + if(Peek16le(s) == p0 && s[2] == p1) + return (int)(s - ptr); + s += step; + } + } + else + if(len == 2) { + int16 p0 = Peek16le(p); + while(s <= e) { + if(Peek16le(s) == p0) + return (int)(s - ptr); + s += step; + } + } + else + if(len == 1) { + char p0 = p[0]; + while(s <= e) { + if(*s == p0) + return (int)(s - ptr); + s += step; + } + } + else + return true; + } + else { +#ifdef CPU_64 + int64 p0 = Peek64le(p); + if(len <= 16) { + len -= 8; + int64 p1 = Peek64le(p + len); + while(s <= e) { + if(Peek64le(s) == p0 && Peek64le(s + len) == p1) + return (int)(s - ptr); + s += step; + } + } + else + while(s <= e) { + if(Peek64le(s) == p0 && equal_back_8(s, p, len)) + return (int)(s - ptr); + s += step; + } +#else + int32 p0 = Peek32le(p); + while(s <= e) { + if(Peek32le(s) == p0 && equal_back_4(s, p, len)) + return (int)(s - ptr); + s += step; + } +#endif + } + return -1; +} + +int find(const char *text, int len, const char *needle, int nlen, int from) +{ + return t_find<1>(text, len, needle, nlen, from); +} + +int find(const wchar *text, int len, const wchar *needle, int nlen, int from) +{ + return t_find<2>((const char *)text, 2 * len, (const char *)needle, 2 * nlen, from) / 2; +} + +#else + +template +int t_find(const tchar *ptr, int plen, const tchar *s, int len, int from) +{ + ASSERT(from >= 0 && from <= plen); + int l = plen - len - from; + if(l < 0) + return -1; + if(len == 0) + return from; + const tchar *p = ptr + from; + const tchar *e = p + l; + if(len > 4) { + tchar s0 = s[0]; + tchar s1 = s[1]; + tchar s2 = s[2]; + tchar sl = s[len - 1]; + int l_1 = len - 1; + while(p <= e) { + if(s0 == p[0] && sl == p[l_1] && s1 == p[1] && s2 == p[2] && + svo_memeq(s + 3, p + 3, len - 4)) + return (int)(p - ptr); + p++; + } + } + else + if(len == 4) { + tchar s0 = s[0]; + tchar s1 = s[1]; + tchar s2 = s[2]; + tchar s3 = s[3]; + while(p <= e) { + if(s0 == p[0] && s3 == p[3] && s1 == p[1] && s2 == p[2]) + return (int)(p - ptr); + p++; + } + } + else + if(len == 3) { + tchar s0 = s[0]; + tchar s1 = s[1]; + tchar s2 = s[2]; + while(p <= e) { + if(s0 == p[0] && s2 == p[2] && s1 == p[1]) + return (int)(p - ptr); + p++; + } + } + else + if(len == 2) { + tchar s0 = s[0]; + tchar s1 = s[1]; + while(p <= e) { + if(s0 == p[0] && s1 == p[1]) + return (int)(p - ptr); + p++; + } + } + else { + tchar s0 = s[0]; + while(p <= e) { + if(s0 == *p) + return (int)(p - ptr); + p++; + } + } + return -1; +} + +int find(const char *text, int len, const char *needle, int nlen, int from) +{ + return t_find(text, len, needle, nlen, from); +} + +int find(const wchar *text, int len, const wchar *needle, int nlen, int from) +{ + return t_find(text, len, needle, nlen, from); +} +#endif + +END_UPP_NAMESPACE