Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Strnstr and Strnistr implementations #8

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions include/EAStdC/EAString.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
// char_t* Strrchr(const char_t* pString, char_t c);
// size_t Strspn(const char_t* pString, const char_t* pSubString);
// char_t* Strstr(const char_t* pString, const char_t* pSubString);
// char_t* Strnstr(const char_t* pString, const char_t* pSubString, size_t n);
// char_t* Stristr(const char_t* pString, const char_t* pSubString);
// char_t* Strnistr(const char_t* pString, const char_t* pSubString, size_t n);
// bool Strstart(const char_t* pString, const char_t* pPrefix);
// bool Stristart(const char_t* pString, const char_t* pPrefix);
// bool Strend(const char_t* pString, const char_t* pSuffix, size_t stringLength = kSizeTypeUnset);
Expand Down Expand Up @@ -1041,6 +1043,20 @@ EASTDC_API char32_t* Strstr(const char32_t* pString, const char32_t* pSubString)
#endif


/// Strnstr
///
/// Finds the first occurrence of pSubString within pString, exclusive of the
/// terminating null character, where not more than n characters are searched.
/// This is similar to the strnstr C function.
/// Note: Has the same const char return decision that Strstr.
EASTDC_API char* Strnstr(const char* pString, const char* pSubString, size_t n);
EASTDC_API char16_t* Strnstr(const char16_t* pString, const char16_t* pSubString, size_t n);
EASTDC_API char32_t* Strnstr(const char32_t* pString, const char32_t* pSubString, size_t n);
#if EA_WCHAR_UNIQUE
EASTDC_API wchar_t* Strnstr(const wchar_t* pString, const wchar_t* pSubString, size_t n);
#endif


/// Stristr
///
/// This is a case-insensitive version of Strstr.
Expand All @@ -1059,6 +1075,18 @@ EASTDC_API char32_t* Stristr(const char32_t* pString, const char32_t* pSubString
#endif


/// Strnistr
///
/// This is a case-insensitive version of Strnstr.
///
EASTDC_API char* Strnistr(const char* pString, const char* pSubString, size_t n);
EASTDC_API char16_t* Strnistr(const char16_t* pString, const char16_t* pSubString, size_t n);
EASTDC_API char32_t* Strnistr(const char32_t* pString, const char32_t* pSubString, size_t n);
#if EA_WCHAR_UNIQUE
EASTDC_API wchar_t* Strnistr(const wchar_t* pString, const wchar_t* pSubString, size_t n);
#endif


/// Strrstr
///
/// Finds the last occurrence of pSubString within pString, exclusive of the
Expand Down Expand Up @@ -2570,11 +2598,21 @@ namespace StdC
return reinterpret_cast<wchar_t *>(Strstr(EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pString), EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pSubString)));
}

inline wchar_t* Strnstr(const wchar_t* pString, const wchar_t* pSubString, size_t n)
{
return reinterpret_cast<wchar_t *>(Strnstr(EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pString), EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pSubString), n));
}

inline wchar_t* Stristr(const wchar_t* pString, const wchar_t* pSubString)
{
return reinterpret_cast<wchar_t *>(Stristr(EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pString), EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pSubString)));
}

inline wchar_t* Strnistr(const wchar_t* pString, const wchar_t* pSubString, size_t n)
{
return reinterpret_cast<wchar_t *>(Strnistr(EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pString), EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pSubString), n));
}

inline wchar_t* Strrstr(const wchar_t* pString, const wchar_t* pSubString)
{
return reinterpret_cast<wchar_t *>(Strrstr(EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pString), EASTDC_UNICODE_CONST_CHAR_PTR_CAST(pSubString)));
Expand Down
168 changes: 168 additions & 0 deletions source/EAString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,92 @@ EASTDC_API char32_t* Strstr(const char32_t* pString, const char32_t* pSubString)



EASTDC_API char* Strnstr(const char* pString, const char* pSubString, size_t n)
{
if (*pSubString == 0)
return (char*)pString;

size_t len = Strlen(pSubString);

if (n < len)
return 0;

char* s1 = (char*)pString;
for(size_t i = 0; (*s1 != 0) && (i <= n - len) ; ++i, ++s1)
{
if (*s1 == *pSubString)
{
const char* s2 = (s1 - 1);
const char* p2 = (pSubString - 1);
char cs, cp;

while((cs = *++s2) == (cp = *++p2) && cs){} // Do nothing

if(!cp)
return s1;
}
}
return 0;
}

EASTDC_API char16_t* Strnstr(const char16_t* pString, const char16_t* pSubString, size_t n)
{
if (*pSubString == 0)
return (char16_t*)pString;

size_t len = Strlen(pSubString);

if (n < len)
return 0;

char16_t* s1 = (char16_t*)pString;
for(size_t i = 0; (*s1 != 0) && (i <= n - len) ; ++i, ++s1)
{
if (*s1 == *pSubString)
{
const char16_t* s2 = (s1 - 1);
const char16_t* p2 = (pSubString - 1);
char16_t cs, cp;

while((cs = *++s2) == (cp = *++p2) && cs){} // Do nothing

if(!cp)
return s1;
}
}
return 0;
}

EASTDC_API char32_t* Strnstr(const char32_t* pString, const char32_t* pSubString, size_t n)
{
if (*pSubString == 0)
return (char32_t*)pString;

size_t len = Strlen(pSubString);

if (n < len)
return 0;

char32_t* s1 = (char32_t*)pString;
for(size_t i = 0; (*s1 != 0) && (i <= n - len) ; ++i, ++s1)
{
if (*s1 == *pSubString)
{
const char32_t* s2 = (s1 - 1);
const char32_t* p2 = (pSubString - 1);
char32_t cs, cp;

while((cs = *++s2) == (cp = *++p2) && cs){} // Do nothing

if(!cp)
return s1;
}
}
return 0;
}



EASTDC_API char* Stristr(const char* s1, const char* s2)
{
const char* cp = s1;
Expand Down Expand Up @@ -2366,6 +2452,88 @@ EASTDC_API char32_t* Stristr(const char32_t* s1, const char32_t* s2)



EASTDC_API char* Strnistr(const char* pString, const char* pSubString, size_t n)
{
if (*pSubString == 0)
return (char*)pString;

size_t len = Strlen(pSubString);

if (n < len)
return 0;

char* s1 = (char*)pString;
for(size_t i = 0; (*s1 != 0) && (i <= n - len) ; ++i, ++s1)
{
const char* s2 = s1;
const char* p2 = pSubString;

while(*s2 && *p2 && (Tolower(*s2) == Tolower(*p2)))
{
++s2; ++p2;
}

if(*p2 == 0)
return s1;
}
return 0;
}

EASTDC_API char16_t* Strnistr(const char16_t* pString, const char16_t* pSubString, size_t n)
{
if (*pSubString == 0)
return (char16_t*)pString;

size_t len = Strlen(pSubString);

if (n < len)
return 0;

char16_t* s1 = (char16_t*)pString;
for(size_t i = 0; (*s1 != 0) && (i <= n - len) ; ++i, ++s1)
{
const char16_t* s2 = s1;
const char16_t* p2 = pSubString;

while(*s2 && *p2 && (Tolower(*s2) == Tolower(*p2)))
{
++s2; ++p2;
}

if(*p2 == 0)
return s1;
}
return 0;
}

EASTDC_API char32_t* Strnistr(const char32_t* pString, const char32_t* pSubString, size_t n)
{
if (*pSubString == 0)
return (char32_t*)pString;

size_t len = Strlen(pSubString);

if (n < len)
return 0;

char32_t* s1 = (char32_t*)pString;
for(size_t i = 0; (*s1 != 0) && (i <= n - len) ; ++i, ++s1)
{
const char32_t* s2 = s1;
const char32_t* p2 = pSubString;

while(*s2 && *p2 && (Tolower(*s2) == Tolower(*p2)))
{
++s2; ++p2;
}

if(*p2 == 0)
return s1;
}
return 0;
}



EASTDC_API char* Strrstr(const char* s1, const char* s2)
{
Expand Down
79 changes: 79 additions & 0 deletions test/source/TestString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,45 @@ static int TestStringCore()
EATEST_VERIFY(Strstr(s32, EA_CHAR32("abcd")) == &s32[3]);
}

// char* Strnstr(const char* pString, const char* pSubString, size_t n);
// char16_t* Strnstr(const char16_t* pString, const char16_t* pSubString, size_t n);
// char32_t* Strnstr(const char32_t* pString, const char32_t* pSubString, size_t n);
{
char s8[] = "012abcdf89abcdef";

EATEST_VERIFY(Strnstr(s8, "", 0) == &s8[0]);
EATEST_VERIFY(Strnstr(s8, "012", 3) == &s8[0]);
EATEST_VERIFY(Strnstr(s8, "012", 2) == 0);
EATEST_VERIFY(Strnstr(s8, "abcde", 20) == &s8[10]);
EATEST_VERIFY(Strnstr(s8, "abcde", 10) == 0);
EATEST_VERIFY(Strnstr(s8, ":/1", 20) == 0);
EATEST_VERIFY(Strnstr(s8, "abcd", 10) == &s8[3]);
EATEST_VERIFY(Strnstr(s8, "abcd", 5) == 0);
}
{
char16_t s16[24]; Strlcpy(s16, EA_CHAR16("012abcdf89abcdef"), EAArrayCount(s16)); // Can't do char16_t variable[64] = EA_CHAR16(...) because some compilers don't support 16 bit string literals.

EATEST_VERIFY(Strnstr(s16, EA_CHAR16(""), 0) == &s16[0]);
EATEST_VERIFY(Strnstr(s16, EA_CHAR16("012"), 3) == &s16[0]);
EATEST_VERIFY(Strnstr(s16, EA_CHAR16("012"), 2) == 0);
EATEST_VERIFY(Strnstr(s16, EA_CHAR16("abcde"), 20) == &s16[10]);
EATEST_VERIFY(Strnstr(s16, EA_CHAR16("abcde"), 10) == 0);
EATEST_VERIFY(Strnstr(s16, EA_CHAR16(":/1"), 20) == 0);
EATEST_VERIFY(Strnstr(s16, EA_CHAR16("abcd"), 10) == &s16[3]);
EATEST_VERIFY(Strnstr(s16, EA_CHAR16("abcd"), 5) == 0);
}
{
char32_t s32[24]; Strlcpy(s32, EA_CHAR32("012abcdf89abcdef"), EAArrayCount(s32)); // Can't do char32_t variable[64] = EA_CHAR32(...) because some compilers don't support 32 bit string literals.

EATEST_VERIFY(Strnstr(s32, EA_CHAR32(""), 0) == &s32[0]);
EATEST_VERIFY(Strnstr(s32, EA_CHAR32("012"), 3) == &s32[0]);
EATEST_VERIFY(Strnstr(s32, EA_CHAR32("012"), 2) == 0);
EATEST_VERIFY(Strnstr(s32, EA_CHAR32("abcde"), 20) == &s32[10]);
EATEST_VERIFY(Strnstr(s32, EA_CHAR32("abcde"), 10) == 0);
EATEST_VERIFY(Strnstr(s32, EA_CHAR32(":/1"), 20) == 0);
EATEST_VERIFY(Strnstr(s32, EA_CHAR32("abcd"), 10) == &s32[3]);
EATEST_VERIFY(Strnstr(s32, EA_CHAR32("abcd"), 5) == 0);
}

// char* Stristr(const char* pString, const char* pSubString);
// char16_t* Stristr(const char16_t* pString, const char16_t* pSubString);
Expand Down Expand Up @@ -1269,6 +1308,46 @@ static int TestStringCore()
}


// char* Strnistr(const char* pString, const char* pSubString, size_t n);
// char16_t* Strnistr(const char16_t* pString, const char16_t* pSubString, size_t n);
// char32_t* Strnistr(const char32_t* pString, const char32_t* pSubString, size_t n);
{
char s8[] = "012aBcdf89aBcDEf";

EATEST_VERIFY(Strnistr(s8, "", 0) == &s8[0]);
EATEST_VERIFY(Strnistr(s8, "012", 3) == &s8[0]);
EATEST_VERIFY(Strnistr(s8, "012", 2) == 0);
EATEST_VERIFY(Strnistr(s8, "abcde", 20) == &s8[10]);
EATEST_VERIFY(Strnistr(s8, "abcde", 10) == 0);
EATEST_VERIFY(Strnistr(s8, ":/1", 20) == 0);
EATEST_VERIFY(Strnistr(s8, "abcd", 10) == &s8[3]);
EATEST_VERIFY(Strnistr(s8, "abcd", 5) == 0);
}
{
char16_t s16[24]; Strlcpy(s16, EA_CHAR16("012aBcdf89aBcDEf"), EAArrayCount(s16)); // Can't do char16_t variable[64] = EA_CHAR16(...) because some compilers don't support 16 bit string literals.

EATEST_VERIFY(Strnistr(s16, EA_CHAR16(""), 0) == &s16[0]);
EATEST_VERIFY(Strnistr(s16, EA_CHAR16("012"), 3) == &s16[0]);
EATEST_VERIFY(Strnistr(s16, EA_CHAR16("012"), 2) == 0);
EATEST_VERIFY(Strnistr(s16, EA_CHAR16("abcde"), 20) == &s16[10]);
EATEST_VERIFY(Strnistr(s16, EA_CHAR16("abcde"), 10) == 0);
EATEST_VERIFY(Strnistr(s16, EA_CHAR16(":/1"), 20) == 0);
EATEST_VERIFY(Strnistr(s16, EA_CHAR16("abcd"), 10) == &s16[3]);
EATEST_VERIFY(Strnistr(s16, EA_CHAR16("abcd"), 5) == 0);
}
{
char32_t s32[24]; Strlcpy(s32, EA_CHAR32("012aBcdf89aBcDEf"), EAArrayCount(s32)); // Can't do char32_t variable[64] = EA_CHAR32(...) because some compilers don't support 32 bit string literals.

EATEST_VERIFY(Strnistr(s32, EA_CHAR32(""), 0) == &s32[0]);
EATEST_VERIFY(Strnistr(s32, EA_CHAR32("012"), 3) == &s32[0]);
EATEST_VERIFY(Strnistr(s32, EA_CHAR32("012"), 2) == 0);
EATEST_VERIFY(Strnistr(s32, EA_CHAR32("abcde"), 20) == &s32[10]);
EATEST_VERIFY(Strnistr(s32, EA_CHAR32("abcde"), 10) == 0);
EATEST_VERIFY(Strnistr(s32, EA_CHAR32(":/1"), 20) == 0);
EATEST_VERIFY(Strnistr(s32, EA_CHAR32("abcd"), 10) == &s32[3]);
EATEST_VERIFY(Strnistr(s32, EA_CHAR32("abcd"), 5) == 0);
}

// char* Strrstr(const char* pString, const char* pSubString);
// char16_t* Strrstr(const char16_t* pString, const char16_t* pSubString);
// char32_t* Strrstr(const char32_t* pString, const char32_t* pSubString);
Expand Down