mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
more memory functions
This commit is contained in:
parent
cc8fb10e21
commit
47eb87d3ec
@ -20,26 +20,90 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "pgmspace.h"
|
#include "pgmspace.h"
|
||||||
|
|
||||||
size_t strnlen_P(const char* s, size_t size) {
|
size_t strnlen_P(PGM_P s, size_t size) {
|
||||||
const char* cp;
|
const char* cp;
|
||||||
for (cp = s; size != 0 && pgm_read_byte(cp) != '\0'; cp++, size--);
|
for (cp = s; size != 0 && pgm_read_byte(cp) != '\0'; cp++, size--);
|
||||||
return (size_t) (cp - s);
|
return (size_t) (cp - s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* memcpy_P(void* dest, const void* src, size_t count) {
|
|
||||||
const uint8_t* read = reinterpret_cast<const uint8_t*>(src);
|
|
||||||
uint8_t* write = reinterpret_cast<uint8_t*>(dest);
|
|
||||||
|
|
||||||
while (count)
|
int memcmp_P(const void* buf1, PGM_VOID_P buf2P, size_t size) {
|
||||||
{
|
int result = 0;
|
||||||
*write++ = pgm_read_byte(read++);
|
const uint8_t* read1 = (const uint8_t*)buf1;
|
||||||
|
const uint8_t* read2 = (const uint8_t*)buf2P;
|
||||||
|
|
||||||
|
while (size > 0) {
|
||||||
|
uint8_t ch2 = pgm_read_byte(read2);
|
||||||
|
uint8_t ch1 = *read1;
|
||||||
|
if (ch1 != ch2) {
|
||||||
|
result = (int)(ch1)-(int)(ch2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
read1++;
|
||||||
|
read2++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memccpy_P(void* dest, PGM_VOID_P src, int c, size_t count) {
|
||||||
|
uint8_t* read = (uint8_t*)src;
|
||||||
|
uint8_t* write = (uint8_t*)dest;
|
||||||
|
void* result = NULL;
|
||||||
|
|
||||||
|
while (count > 0) {
|
||||||
|
uint8_t ch = pgm_read_byte(read++);
|
||||||
|
*write++ = ch;
|
||||||
count--;
|
count--;
|
||||||
|
if (c == ch) {
|
||||||
|
return write; // the value after the found c
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dest;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* strncpy_P(char* dest, const char* src, size_t size) {
|
void* memmem_P(const void* buf, size_t bufSize, PGM_VOID_P findP, size_t findPSize) {
|
||||||
|
const uint8_t* read = (const uint8_t*)buf;
|
||||||
|
const uint8_t* find = (uint8_t*)findP;
|
||||||
|
uint8_t first = pgm_read_byte(find++);
|
||||||
|
|
||||||
|
findPSize--;
|
||||||
|
|
||||||
|
while (bufSize > 0) {
|
||||||
|
if (*read == first) {
|
||||||
|
size_t findSize = findPSize;
|
||||||
|
const uint8_t* tag = read + 1;
|
||||||
|
size_t tagBufSize = bufSize - 1;
|
||||||
|
const uint8_t* findTag = find;
|
||||||
|
|
||||||
|
while (tagBufSize > 0 && findSize > 0) {
|
||||||
|
uint8_t ch = pgm_read_byte(findTag++);
|
||||||
|
if (ch != *tag) {
|
||||||
|
bufSize--;
|
||||||
|
read++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
findSize--;
|
||||||
|
tagBufSize--;
|
||||||
|
tag++;
|
||||||
|
}
|
||||||
|
if (findSize == 0) {
|
||||||
|
return (void*)read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bufSize--;
|
||||||
|
read++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* strncpy_P(char* dest, PGM_P src, size_t size) {
|
||||||
const char* read = src;
|
const char* read = src;
|
||||||
char* write = dest;
|
char* write = dest;
|
||||||
char ch = '.';
|
char ch = '.';
|
||||||
@ -53,7 +117,7 @@ char* strncpy_P(char* dest, const char* src, size_t size) {
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* strncat_P(char* dest, const char* src, size_t size) {
|
char* strncat_P(char* dest, PGM_P src, size_t size) {
|
||||||
char* write = dest;
|
char* write = dest;
|
||||||
|
|
||||||
while (*write != '\0')
|
while (*write != '\0')
|
||||||
@ -80,7 +144,7 @@ char* strncat_P(char* dest, const char* src, size_t size) {
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncmp_P(const char* str1, const char* str2P, size_t size) {
|
int strncmp_P(const char* str1, PGM_P str2P, size_t size) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
@ -99,7 +163,7 @@ int strncmp_P(const char* str1, const char* str2P, size_t size) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncasecmp_P(const char* str1, const char* str2P, size_t size) {
|
int strncasecmp_P(const char* str1, PGM_P str2P, size_t size) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
@ -118,7 +182,7 @@ int strncasecmp_P(const char* str1, const char* str2P, size_t size) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf_P(const char* formatP, ...) {
|
int printf_P(PGM_P formatP, ...) {
|
||||||
int ret;
|
int ret;
|
||||||
va_list arglist;
|
va_list arglist;
|
||||||
va_start(arglist, formatP);
|
va_start(arglist, formatP);
|
||||||
@ -135,7 +199,7 @@ int printf_P(const char* formatP, ...) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprintf_P(char* str, const char* formatP, ...) {
|
int sprintf_P(char* str, PGM_P formatP, ...) {
|
||||||
int ret;
|
int ret;
|
||||||
va_list arglist;
|
va_list arglist;
|
||||||
va_start(arglist, formatP);
|
va_start(arglist, formatP);
|
||||||
@ -146,7 +210,7 @@ int sprintf_P(char* str, const char* formatP, ...) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snprintf_P(char* str, size_t strSize, const char* formatP, ...) {
|
int snprintf_P(char* str, size_t strSize, PGM_P formatP, ...) {
|
||||||
int ret;
|
int ret;
|
||||||
va_list arglist;
|
va_list arglist;
|
||||||
va_start(arglist, formatP);
|
va_start(arglist, formatP);
|
||||||
@ -157,7 +221,7 @@ int snprintf_P(char* str, size_t strSize, const char* formatP, ...) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsnprintf_P(char* str, size_t strSize, const char* formatP, va_list ap) {
|
int vsnprintf_P(char* str, size_t strSize, PGM_P formatP, va_list ap) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
size_t fmtLen = strlen_P(formatP);
|
size_t fmtLen = strlen_P(formatP);
|
||||||
|
@ -32,27 +32,40 @@ typedef uint32_t prog_uint32_t;
|
|||||||
|
|
||||||
#define SIZE_IRRELEVANT 0x7fffffff
|
#define SIZE_IRRELEVANT 0x7fffffff
|
||||||
|
|
||||||
void* memcpy_P(void* dest, const void* src, size_t count);
|
// memchr_P and memrchr_P are not implemented due to danger in its use, and
|
||||||
|
// how uninteresting their use is
|
||||||
|
// since its a flash string, you should already know where the char is within it,
|
||||||
|
// further, it could return a pointer into the flash memory that is not 32bit aligned
|
||||||
|
// which could cause an exception if read
|
||||||
|
// PGM_VOID_P memchr_P(PGM_VOID_P bufP, int c, size_t count);
|
||||||
|
// PGM_VOID_P memrchr_P(PGM_VOID_P bufP, int c, size_t count);
|
||||||
|
|
||||||
char* strncpy_P(char* dest, const char* src, size_t size);
|
int memcmp_P(const void* buf1, PGM_VOID_P buf2P, size_t size);
|
||||||
|
// memccpy_P is only valid when used with pointers to 8bit data, due to size aligned pointers
|
||||||
|
// and endianess of the values greater than 8bit, matching c may return invalid aligned pointers
|
||||||
|
void* memccpy_P(void* dest, PGM_VOID_P src, int c, size_t count);
|
||||||
|
void* memmem_P(const void* buf, size_t bufSize, PGM_VOID_P findP, size_t findPSize);
|
||||||
|
void* memcpy_P(void* dest, PGM_VOID_P src, size_t count);
|
||||||
|
|
||||||
|
char* strncpy_P(char* dest, PGM_P src, size_t size);
|
||||||
#define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT)
|
#define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT)
|
||||||
|
|
||||||
char* strncat_P(char* dest, const char* src, size_t size);
|
char* strncat_P(char* dest, PGM_P src, size_t size);
|
||||||
#define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT)
|
#define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT)
|
||||||
|
|
||||||
int strncmp_P(const char* str1, const char* str2P, size_t size);
|
int strncmp_P(const char* str1, PGM_P str2P, size_t size);
|
||||||
#define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT)
|
#define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT)
|
||||||
|
|
||||||
int strncasecmp_P(const char* str1, const char* str2P, size_t size);
|
int strncasecmp_P(const char* str1, PGM_P str2P, size_t size);
|
||||||
#define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT)
|
#define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT)
|
||||||
|
|
||||||
size_t strnlen_P(const char *s, size_t size);
|
size_t strnlen_P(PGM_P s, size_t size);
|
||||||
#define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT)
|
#define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT)
|
||||||
|
|
||||||
int printf_P(const char *formatP, ...) __attribute__ ((format (printf, 1, 2)));
|
int printf_P(PGM_P formatP, ...) __attribute__((format(printf, 1, 2)));
|
||||||
int sprintf_P(char *str, const char *formatP, ...) __attribute__((format(printf, 2, 3)));
|
int sprintf_P(char *str, PGM_P formatP, ...) __attribute__((format(printf, 2, 3)));
|
||||||
int snprintf_P(char *str, size_t strSize, const char *formatP, ...) __attribute__((format(printf, 3, 4)));
|
int snprintf_P(char *str, size_t strSize, PGM_P formatP, ...) __attribute__((format(printf, 3, 4)));
|
||||||
int vsnprintf_P(char *str, size_t strSize, const char *formatP, va_list ap) __attribute__ ((format (printf, 3, 0)));
|
int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribute__((format(printf, 3, 0)));
|
||||||
|
|
||||||
// flash memory must be read using 32 bit aligned addresses else a processor
|
// flash memory must be read using 32 bit aligned addresses else a processor
|
||||||
// exception will be triggered
|
// exception will be triggered
|
||||||
|
Loading…
x
Reference in New Issue
Block a user