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
Changes from 1 commit
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
Next Next commit
adding Strnstr implementation
  • Loading branch information
zhensydow committed Jun 25, 2020
commit ff5271fd95a8360bc89c0da27495ae393a20f576
20 changes: 20 additions & 0 deletions include/EAStdC/EAString.h
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
// 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);
// bool Strstart(const char_t* pString, const char_t* pPrefix);
// bool Stristart(const char_t* pString, const char_t* pPrefix);
@@ -1041,6 +1042,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.
@@ -2570,6 +2585,11 @@ 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)));
86 changes: 86 additions & 0 deletions source/EAString.cpp
Original file line number Diff line number Diff line change
@@ -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;
39 changes: 39 additions & 0 deletions test/source/TestString.cpp
Original file line number Diff line number Diff line change
@@ -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);