EAString

Introduction

EACRT stands for EA C Runtime. EACRT implements an extensive suite of C string functionality in a portable way. Some of this functionality is the same as what is present in the C standard and in common (but non-portable) extensions to the C standard. EACRT presents a consistent portable interface to its functionality in both 8 bit and 16 bit string form.

The C language provides various functions which work with non-portable data types, such as long. EACRT defines all significant data types in terms of portable types such as int32_t and int64_t.

Additionally, the EACRT versions of functions are usually faster than the C runtime library versions, usually because the EACRT versions minimize cache misses and branching, whereas typical C runtime libraries optimize for the smallest memory footprint with little or no regard to other performance characteristics.

C-style printf functionality is separate from EACRT and is found in EASprintf. Memcpy functionality (which comes from the C string.h header file) is present in EAMemcpy. However, EACRT has a few mem functions itself.

In some cases, EACRT simply #defines its function to be the same as the equivalent C function. This is done when the equivalent C function is known to be present and known to conform to the C/C++ language standard correctly.

Extension functions

EACRT provides extended functionality that isn't found in conventional C libraries, but it useful nevertheless.

Function Description Signature
Strlcat Safe variation of strncat char_t* Strlcat(char_t* pDestination, const char_t* pSource, size_t n);
Strlcpy Safe variation of strcpy char_t* Strlcpy(char_t* pDestination, const char_t* pSource, size_t n);
Stristr Case insensitive version of strstr (find string within string) char_t* Stristr(const char_t* pString, const char_t* pSubString);
FtoaEnglish

Float to ascii; always use English numeric format, regardless of the current locale.

char_t* FtoaEnglish(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled);
AtofEnglish Ascii to float; always use English numeric format, regardless of the current locale. double AtofEnglish(const char_t* pString);
StrtodEnglish Same as strtod, but always use English numeric format, regardless of the current locale. double StrtodEnglish(const char_t* pString, char_t** ppStringEnd);
Memset16 Sets 16 bit values in memory (as opposed to memset's 8 bit values) uint16_t* Memset16(void* pDestination, uint16_t c, size_t count);
Memset32 Sets 32 bit values in memory (as opposed to memset's 8 bit values) uint32_t* Memset32(void* pDestination, uint32_t c, size_t count);
Memset64 Sets 64 bit values in memory (as opposed to memset's 8 bit values) uint64_t* Memset64(void* pDestination, uint64_t c, size_t count);
MemsetN Sets arbitrarily sized values in memory. void* MemsetN (void* pDestination, const void* pSource, size_t sourceBytes, size_t count);
EcvtBuf Base function for converting a float to a %e string.

char_t* EcvtBuf(double dValue, int nDigitCount, int* decimalPos, int* sign, char_t* buffer);

FcvtBuf Base function for converting a float to a %f string. char_t* FcvtBuf(double dValue, int nDigitCountAfterDecimal, int* decimalPos, int* sign, char_t* buffer);

 

Example usage

We provide a random smattering of example code here.

char16_t buffer[32] = L"hello ";

Strcat16(buffer, L"world");

Strlcat:

char buffer[32];

Strlcpy8(buffer, "Hello ", sizeof(buffer));
Strlcat8(buffer, "world", sizeof(buffer));

U64toa:

char buffer[32];

U64toa8(UINT64_C(12345678901234567890), buffer, 16);

AtoI32:

int32_t x = AtoI328("1234567890");

StrtodEnglish:

const char16_t* pString = L"12345.678 123.456 1.23456";

while(*pString)
{
    double value = StrtodEnglish16(pString, &pString);
    printf("Field = %f\n, value);
}

Memset16:

uint16_t buffer[50];

Memset16(buffer, 0x1234, 50);

Interface

In each of the functions below, there is an char8_t and char16_t version. The actual function that EACRT implements is one with an 8 or 16 appended to the function names listed below. Thus below we have Strcat(char_t*, char_t*), and thus EACRT presents Strcat8(char8_t*, char8_t*) and Strcat16(char16_t*, char16_t*).

See EACRT.h for per-function documentation.

char_t*       Strcat(char_t* pDestination, const char_t* pSource);
char_t*       Strncat(char_t* pDestination, const char_t* pSource, size_t n);
char_t*       Strlcat(char_t* pDestination, const char_t* pSource, size_t n);
char_t*       Strcpy(char_t* pDestination, const char_t* pSource);
char_t*       Strncpy(char_t* pDestination, const char_t* pSource, size_t n);
char_t*       Strlcpy(char_t* pDestination, const char_t* pSource, size_t n);
size_t        Strlen(const char_t* pString);
size_t        Strxfrm(char_t* pDest, const char_t* pSource, size_t n);
char_t*       Strdup(const char_t* pString);

int           Isalnum(char_t c);
int           Isalpha(char_t c);
int           Isdigit(char_t c);
int           Isxdigit(char_t c);
int           Isgraph(char_t c);
int           Islower(char_t c);
int           Isprint(char_t c);
int           Ispunct(char_t c);
int           Isspace(char_t c);
int           Iscntrl(char_t c);
int           Isascii(char_t c);
int           Toupper(char_t c);
int           Tolower(char_t c);

char_t*       Strlwr(char_t* pString);
char_t*       Strupr(char_t* pString);
char_t*       Strchr(const char_t* pString, char_t c);
size_t        Strcspn(const char_t* pString1, const char_t* pString2);
char_t*       Strpbrk(const char_t* pString1, const char_t* pString2);
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*       Stristr(const char_t* pString, const char_t* pSubString);
char_t*       Strtok(char_t* pString, const char_t*  pTokens, char_t** pContext);
char_t*       Strset(char_t* pString, char_t c);
char_t*       Strnset(char_t* pString, char_t c, size_t n);
char_t*       Strrev(char_t* pString);
int           Strcmp(const char_t* pString1, const char_t* pString2);
int           Strncmp(const char_t* pString1, const char_t* pString2, size_t n);
int           Stricmp(const char_t*  pString1, const char_t* pString2);
int           Strnicmp(const char_t* pString1, const char_t* pString2, size_t n);
int           Strcoll(const char_t*  pString1, const char_t* pString2);
int           Strncoll(const char_t* pString1, const char_t* pString2, size_t n);
int           Stricoll(const char_t* pString1, const char_t* pString2);
int           Strnicoll(const char_t* pString1, const char_t* pString1, size_t n);

char_t*       EcvtBuf(double dValue, int nDigitCount, int* decimalPos, int* sign, char_t* buffer);
char_t*       FcvtBuf(double dValue, int nDigitCountAfterDecimal, int* decimalPos, int* sign, char_t* buffer);

char_t*       I32toa(int32_t nValue, char_t* pResult, int nBase);
char_t*       U32toa(uint32_t nValue, char_t* pResult, int nBase);
char_t*       I64toa(int64_t nValue, char_t* pBuffer, int nBase);
char_t*       U64toa(uint64_t nValue, char_t* pBuffer, int nBase);
double        Strtod(const char_t* pString, char_t** ppStringEnd);
double        StrtodEnglish(const char_t* pString, char_t** ppStringEnd);
int64_t       StrtoI64(const char_t* pString, char_t** ppStringEnd, int nBase);
uint64_t      StrtoU64(const char_t* pString, char_t** ppStringEnd, int nBase);
int32_t       StrtoI32(const char_t* pString, char_t** ppStringEnd, int nBase);
uint32_t      StrtoU32(const char_t* pString, char_t** ppStringEnd, int nBase);
int32_t       AtoI32(const char_t* pString);
uint32_t      AtoU32(const char_t* pString);
int64_t       AtoI64(const char_t* pString);
uint64_t      AtoU64(const char_t* pString);
double        Atof(const char_t* pString);
double        AtofEnglish(const char_t* pString);
char_t*       Ftoa(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled);
char_t*       FtoaEnglish(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled);

uint8_t*      Memset8 (void* pDestination, uint8_t  c, size_t count);
uint16_t*     Memset16(void* pDestination, uint16_t c, size_t count);
uint32_t*     Memset32(void* pDestination, uint32_t c, size_t count);
uint64_t*     Memset64(void* pDestination, uint64_t c, size_t count);
void*         MemsetN (void* pDestination, const void* pSource, size_t sourceBytes, size_t count);
const char_t* Memchr(const char_t* pString, char_t c, size_t n);
int           Memcmp(const char_t* pString1, const char_t* pString2, size_t n);
char_t*       Memcpy(char_t* pDestination, const char_t* pSource, size_t n);
char_t*       Memmove(char_t* pDestination, const char_t* pSource, size_t n);
char_t*       Memset(char_t* pString, char_t c, size_t n);