LCOV - code coverage report
Current view: top level - src - endianness.c (source / functions) Coverage Total Hit
Test: pino Coverage Report Lines: 99.0 % 98 97
Test Date: 2025-10-24 02:48:56 Functions: 100.0 % 22 22
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              :  * libpino - endianness.c
       3              :  * 
       4              :  */
       5              : 
       6              : #include <pino/endianness.h>
       7              : 
       8              : #include <pino_internal.h>
       9              : 
      10              : #define ENDIANNESS_UNKNOWN      0
      11              : #define ENDIANNESS_LITTLE       1
      12              : #define ENDIANNESS_BIG          2
      13              : 
      14              : #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      15              : static uint8_t g_endianness = ENDIANNESS_LITTLE;
      16              : #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
      17              : static uint8_t g_endianness = ENDIANNESS_BIG;
      18              : #else
      19              : static uint8_t g_endianness = ENDIANNESS_UNKNOWN;
      20              : #endif
      21              : 
      22         3094 : static inline uint8_t platform_endianness(void)
      23              : {
      24              :     uint32_t i;
      25              :     uint8_t *p;
      26              :     
      27         3094 :     if (g_endianness != ENDIANNESS_UNKNOWN) {
      28         3094 :         return g_endianness;
      29              :     }
      30              : 
      31              :     /* LCOV_EXCL_START */
      32              : 
      33              :     i = 1;
      34              :     p = (uint8_t *)&i;
      35              : 
      36              :     return g_endianness = (p[0] == 1) ? ENDIANNESS_LITTLE : ENDIANNESS_BIG;
      37              : 
      38              :     /* LCOV_EXCL_STOP */
      39              : }
      40              : 
      41            4 : static inline uint16_t bswap16(uint16_t x)
      42              : {
      43            4 :     return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
      44              : }
      45              : 
      46           16 : static inline uint32_t bswap32(uint32_t x)
      47              : {
      48           16 :     return ((x & 0xff) << 24) | 
      49           16 :            ((x & 0xff00) << 8) | 
      50           32 :            ((x & 0xff0000) >> 8) | 
      51           16 :            ((x & 0xff000000) >> 24);
      52              : }
      53              : 
      54            6 : static inline uint64_t bswap64(uint64_t x)
      55              : {
      56            6 :     return ((x & 0xff) << 56) | 
      57            6 :            ((x & 0xff00) << 40) | 
      58            6 :            ((x & 0xff0000) << 24) | 
      59            6 :            ((x & 0xff000000) << 8) | 
      60            6 :            ((x & 0xff00000000ULL) >> 8) | 
      61            6 :            ((x & 0xff0000000000ULL) >> 24) | 
      62           12 :            ((x & 0xff000000000000ULL) >> 40) | 
      63            6 :            ((x & 0xff00000000000000ULL) >> 56);
      64              : }
      65              : 
      66           30 : static inline void *bswap_memcpy(void *dest, const void *src, size_t size, size_t elem_size)
      67              : {
      68              :     uint8_t *dp;
      69              :     const uint8_t *sp;
      70              :     size_t i, j;
      71              :     uint16_t *dest16, *src16;
      72              :     uint32_t *dest32, *src32;
      73              :     uint64_t *dest64, *src64;
      74              : 
      75           30 :     dp = (uint8_t *)dest;
      76           30 :     sp = (const uint8_t *)src;
      77              : 
      78           30 :     if (elem_size == 1 || size == 0) {
      79            2 :         return pmemcpy(dest, src, size);
      80              :     }
      81              : 
      82           28 :     if (elem_size == 2 && (((uintptr_t)dest | (uintptr_t)src) & 0x1) == 0) {
      83            4 :         dest16 = (uint16_t *)dest;
      84            4 :         src16 = (uint16_t *)src;
      85              : 
      86            8 :         for (i = 0; i < size / 2; i++) {
      87            4 :             dest16[i] = bswap16(src16[i]);
      88              :         }
      89              : 
      90            4 :         return dest;
      91           24 :     } else if (elem_size == 4 && (((uintptr_t)dest | (uintptr_t)src) & 0x3) == 0) {
      92           16 :         dest32 = (uint32_t *)dest;
      93           16 :         src32 = (uint32_t *)src;
      94              : 
      95           32 :         for (i = 0; i < size / 4; i++) {
      96           16 :             dest32[i] = bswap32(src32[i]);
      97              :         }
      98              : 
      99           16 :         return dest;
     100            8 :     } else if (elem_size == 8 && (((uintptr_t)dest | (uintptr_t)src) & 0x7) == 0) {
     101            6 :         dest64 = (uint64_t *)dest;
     102            6 :         src64 = (uint64_t *)src;
     103              : 
     104           12 :         for (i = 0; i < size / 8; i++) {
     105            6 :             dest64[i] = bswap64(src64[i]);
     106              :         }
     107              : 
     108            6 :         return dest;
     109              :     }
     110              : 
     111            4 :     for (i = 0; i < size; i += elem_size) {
     112            6 :         for (j = 0; j < elem_size; j++) {
     113            4 :             dp[i + j] = sp[i + (elem_size - 1 - j)];
     114              :         }
     115              :     }
     116              : 
     117            2 :     return dest;
     118              : }
     119              : 
     120           24 : static inline size_t elem_sizeof(size_t size)
     121              : {
     122           24 :     if (size == 1 || size == 2 || size == 4 || size == 8) {
     123           24 :         return size;
     124              :     }
     125              : 
     126            0 :     return 1;
     127              : }
     128              : 
     129           10 : static inline void *conv_memcpy(void *dest, const void *src, size_t size)
     130              : {
     131           10 :     return bswap_memcpy(dest, src, size, elem_sizeof(size));
     132              : }
     133              : 
     134         3066 : static inline void *memcpy_common(void *dest, const void *src, size_t size, bool is_native)
     135              : {
     136         3066 :     return is_native ? pmemcpy(dest, src, size) : conv_memcpy(dest, src, size);
     137              : }
     138              : 
     139           16 : static inline void *memmove_common(void *dest, const void *src, size_t size, bool is_native)
     140              : {
     141              :     uint8_t *tmp;
     142              : 
     143           16 :     if (is_native) {
     144            8 :         return pmemmove(dest, src, size);
     145              :     } else {
     146            8 :         tmp = (uint8_t *)pmalloc(size);
     147              :         /* LCOV_EXCL_START */
     148              :         if (tmp == NULL) {
     149              :             PINO_SUPRTF("pmalloc failed");
     150              :             return NULL;
     151              :         }
     152              :         /* LCOV_EXCL_STOP */
     153              : 
     154            8 :         pmemcpy(tmp, src, size);
     155            8 :         bswap_memcpy(dest, tmp, size, elem_sizeof(size));
     156              : 
     157            8 :         pfree(tmp);
     158              : 
     159            8 :         return dest;
     160              :     }
     161              : 
     162              :     /* LCOV_EXCL_START */
     163              :     PINO_SUPUNREACH();
     164              :     return NULL;
     165              :     /* LCOV_EXCL_STOP */
     166              : }
     167              : 
     168           12 : static inline int memcmp_common(const void *s1, const void *s2, size_t size, bool is_native)
     169              : {
     170              :     uint8_t *tmp1, *tmp2;
     171              :     size_t elem_size;
     172              :     int result;
     173              : 
     174           12 :     if (is_native) {
     175            6 :         return pmemcmp(s1, s2, size);
     176              :     } else {
     177            6 :         tmp1 = (uint8_t *)pmalloc(size);
     178            6 :         tmp2 = (uint8_t *)pmalloc(size);
     179              :         /* LCOV_EXCL_START */
     180              :         if (!tmp1 || !tmp2) {
     181              :             PINO_SUPRTF("pmalloc failed");
     182              : 
     183              :             if (tmp1) {
     184              :                 pfree(tmp1);
     185              :             }
     186              : 
     187              :             if (tmp2) {
     188              :                 pfree(tmp2);
     189              :             }
     190              : 
     191              :             return 0;
     192              :         }
     193              :         /* LCOV_EXCL_STOP */
     194              : 
     195            6 :         elem_size = elem_sizeof(size);
     196            6 :         bswap_memcpy(tmp1, s1, size, elem_size);
     197            6 :         bswap_memcpy(tmp2, s2, size, elem_size);
     198              : 
     199            6 :         result = pmemcmp(tmp1, tmp2, size);
     200              : 
     201            6 :         pfree(tmp1);
     202            6 :         pfree(tmp2);
     203              : 
     204            6 :         return result;
     205              :     }
     206              : 
     207              :     /* LCOV_EXCL_START */
     208              :     PINO_SUPUNREACH();
     209              :     return 0;
     210              :     /* LCOV_EXCL_STOP */
     211              : }
     212              : 
     213         1037 : extern void *pino_endianness_memcpy_le2native(void *dest, const void *src, size_t size)
     214              : {    
     215         1037 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     216              : }
     217              : 
     218            5 : extern void *pino_endianness_memcpy_be2native(void *dest, const void *src, size_t size)
     219              : {   
     220            5 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     221              : }
     222              : 
     223         2019 : extern void *pino_endianness_memcpy_native2le(void *dest, const void *src, size_t size)
     224              : {
     225         2019 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     226              : }
     227              : 
     228            5 : extern void *pino_endianness_memcpy_native2be(void *dest, const void *src, size_t size)
     229              : {
     230            5 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     231              : }
     232              : 
     233            4 : extern void *pino_endianness_memmove_le2native(void *dest, const void *src, size_t size)
     234              : {
     235            4 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     236              : }
     237              : 
     238            3 : extern void *pino_endianness_memmove_be2native(void *dest, const void *src, size_t size)
     239              : {
     240            3 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     241              : }
     242              : 
     243            4 : extern void *pino_endianness_memmove_native2le(void *dest, const void *src, size_t size)
     244              : {
     245            4 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     246              : }
     247              : 
     248            5 : extern void *pino_endianness_memmove_native2be(void *dest, const void *src, size_t size)
     249              : {
     250            5 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     251              : }
     252              : 
     253            3 : extern int pino_endianness_memcmp_le2native(const void *s1, const void *s2, size_t size)
     254              : {
     255            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_LITTLE));
     256              : }
     257              : 
     258            3 : extern int pino_endianness_memcmp_be2native(const void *s1, const void *s2, size_t size)
     259              : {
     260            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_BIG));
     261              : }
     262              : 
     263            3 : extern int pino_endianness_memcmp_native2le(const void *s1, const void *s2, size_t size)
     264              : {
     265            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_LITTLE));
     266              : }
     267              : 
     268            3 : extern int pino_endianness_memcmp_native2be(const void *s1, const void *s2, size_t size)
     269              : {
     270            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_BIG));
     271              : }
        

Generated by: LCOV version 2.0-1