/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#ifndef INCLUDE_ECXX_PLATFORM_SPECIFIC_PROGMEM_FUNCTOR_H
#error "this file cannot be included directly"
#endif
#undef INCLUDE_ECXX_PLATFORM_SPECIFIC_PROGMEM_FUNCTOR_H


#ifndef ECXX_PLATFORM_COMMON_PROGMEM_FUNCTOR_H
#define ECXX_PLATFORM_COMMON_PROGMEM_FUNCTOR_H


namespace eCxx {


//
// Platform-specific's program-memory functors
//

// Inform that the platform-specific's program-memory functors have been defined here
#define ECXX_PROGMEM_FUNCTOR_DEFINED

// Read a byte
struct PGMReadByte {
    inline uint8_t operator()(_PGMVoidPointer ptr) const noexcept
    { return *static_cast<const uint8_t*>(ptr); }
};

// Read a word
struct PGMReadWord {
    inline uint16_t operator()(_PGMVoidPointer ptr) const noexcept
    { return *static_cast<const uint16_t*>(ptr); }
};

// Read a dword
struct PGMReadDWord {
    inline uint32_t operator()(_PGMVoidPointer ptr) const noexcept
    { return *static_cast<const uint32_t*>(ptr); }
};

// Memory copy
struct PGMMemCpy {
    inline void operator()(void* dst, _PGMVoidPointer src, size_t len) const noexcept
    { memcpy(dst, src, len); }
};

// String copy
struct PGMStrNCpy {
    inline void operator()(char* dst, _PGMCharPointer src, size_t max) const noexcept
    { strncpy(dst, src, max); }
};

// String compare
struct PGMStrNCmp {
    inline int operator()(const char* ptr1, _PGMCharPointer ptr2, size_t max) const noexcept
    { return strncmp(ptr1, ptr2, max); }
};

// String length
struct PGMStrNLen {
    inline size_t operator()(_PGMCharPointer ptr, size_t max) const noexcept
    { return strnlen(ptr, max); }
};


} // namespace eCxx


#endif
