CloverBootloader/rEFIt_UEFI/PlatformEFI/posix/string.cpp
2021-05-09 17:20:24 +03:00

179 lines
4.0 KiB
C++

#include <posix.h>
// Function to implement strncat() function in C
char* strncat(char* destination, const char* source, size_t num)
{
// make ptr point to the end of destination string
char* ptr = destination + strlen(destination);
// Appends characters of source to the destination string
while (*source != '\0' && num--)
*ptr++ = *source++;
// null terminate destination string
*ptr = '\0';
// destination string is returned by standard strncat()
return destination;
}
#ifndef strcmp
/*
* Taken from glibc. Seems not optimized at all...
*/
/* Compare S1 and S2, returning less than, equal to or
greater than zero if S1 is lexicographically less than,
equal to or greater than S2. */
int strcmp (const char *p1, const char *p2)
{
const unsigned char *s1 = (const unsigned char *) p1;
const unsigned char *s2 = (const unsigned char *) p2;
unsigned char c1, c2;
do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2);
return c1 - c2;
}
#endif
#ifndef strncmp
// faster implementation than AsciiStrnCmp. AsciiStrnCmp calls AsciiStrSize 4 times.
//int strncmp( const char * s1, const char * s2, size_t n )
//{
// while ( n && *s1 && ( *s1 == *s2 ) )
// {
// ++s1;
// ++s2;
// --n;
// }
// if ( n == 0 )
// {
// return 0;
// }
// else
// {
// return ( *(unsigned char *)s1 - *(unsigned char *)s2 );
// }
//}
/* Compare no more than N characters of S1 and S2,
returning less than, equal to or greater than zero
if S1 is lexicographically less than, equal to or
greater than S2. */
int
strncmp(const char *s1, const char *s2, size_t n)
{
unsigned char c1 = '\0';
unsigned char c2 = '\0';
if (n >= 4)
{
size_t n4 = n >> 2;
do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c1 - c2;
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c1 - c2;
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c1 - c2;
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c1 - c2;
} while (--n4 > 0);
n &= 3;
}
while (n > 0)
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c1 - c2;
n--;
}
return c1 - c2;
}
//
//// Got his here : http://mgronhol.github.io/fast-strcmp/
//int strncmp_(const char *ptr0, const char *ptr1, size_t len)
//{
// size_t fast = len / sizeof(size_t) + 1;
// size_t offset = (fast - 1) * sizeof(size_t);
// size_t current_block = 0;
//
// if (len < sizeof(size_t)) {
// fast = 0;
// }
//
// size_t *lptr0 = (size_t*) ptr0;
// size_t *lptr1 = (size_t*) ptr1;
//
// while (current_block < fast) {
// if ((lptr0[current_block] ^ lptr1[current_block])) {
// size_t pos;
// for (pos = current_block * sizeof(size_t); pos < len; ++pos) {
// if ((ptr0[pos] ^ ptr1[pos]) || (ptr0[pos] == 0) || (ptr1[pos] == 0)) {
// return (int) ((unsigned char) ptr0[pos] - (unsigned char) ptr1[pos]);
// }
// }
// }
//
// ++current_block;
// }
//
// while (len > offset) {
// if ((ptr0[offset] ^ ptr1[offset])) {
// return (int) ((unsigned char) ptr0[offset] - (unsigned char) ptr1[offset]);
// }
// ++offset;
// }
//
// return 0;
//}
int memcmp(const void *s1, const void *s2, size_t n)
{
if ( n > MAX_UINTN ) {
log_technical_bug("n > MAX_UINTN");
}
INTN ret = CompareMem(s1,s2,(UINTN)(n));
if ( ret < INT_MIN ) {
log_technical_bug("n > ret > MAX_INT");
}
if ( ret > INT_MAX ) {
log_technical_bug("n > ret > MAX_INT");
}
return (int)ret;
}
char* strstr(const char *haystack, const char *needle)
{
return AsciiStrStr(haystack,needle);
}
#endif