LCOV - code coverage report
Current view: top level - src - endianness.c (source / functions) Coverage Total Hit
Test: pino Coverage Report Lines: 87.9 % 66 58
Test Date: 2026-01-22 09:45:38 Functions: 100.0 % 18 18
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              :  * libpino - endianness.c
       3              :  *
       4              :  * This file is part of libpino.
       5              :  *
       6              :  * Author: Go Kudo <zeriyoshi@gmail.com>
       7              :  * SPDX-License-Identifier: MIT
       8              :  */
       9              : 
      10              : #include <pino/endianness.h>
      11              : #include <pino/portable.h>
      12              : 
      13              : #include "internal/bswap.h"
      14              : #include "internal/common.h"
      15              : 
      16              : #define ENDIANNESS_UNKNOWN 0
      17              : #define ENDIANNESS_LITTLE  1
      18              : #define ENDIANNESS_BIG     2
      19              : 
      20              : #define bswap_memcpy pino_bswap_memcpy
      21              : 
      22              : #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      23              : static uint8_t g_endianness = ENDIANNESS_LITTLE;
      24              : #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
      25              : static uint8_t g_endianness = ENDIANNESS_BIG;
      26              : #else
      27              : static uint8_t g_endianness = ENDIANNESS_UNKNOWN;
      28              : #endif
      29              : 
      30         3095 : static inline uint8_t platform_endianness(void)
      31              : {
      32         3095 :     uint32_t i = 1;
      33         3095 :     uint8_t *p = (uint8_t *)&i;
      34              : 
      35         3095 :     if (g_endianness != ENDIANNESS_UNKNOWN) {
      36         3095 :         return g_endianness;
      37              :     }
      38              : 
      39            0 :     return g_endianness = (p[0] == 1) ? ENDIANNESS_LITTLE : ENDIANNESS_BIG;
      40              : }
      41              : 
      42           24 : static inline size_t elem_sizeof(size_t size)
      43              : {
      44           24 :     if (size == 1 || size == 2 || size == 4 || size == 8) {
      45           24 :         return size;
      46              :     }
      47              : 
      48            0 :     return 1;
      49              : }
      50              : 
      51           10 : static inline void *conv_memcpy(void *dest, const void *src, size_t size)
      52              : {
      53           10 :     return bswap_memcpy(dest, src, size, elem_sizeof(size));
      54              : }
      55              : 
      56         3067 : static inline void *memcpy_common(void *dest, const void *src, size_t size, bool is_native)
      57              : {
      58         3067 :     return is_native ? pmemcpy(dest, src, size) : conv_memcpy(dest, src, size);
      59              : }
      60              : 
      61           16 : static inline void *memmove_common(void *dest, const void *src, size_t size, bool is_native)
      62              : {
      63              :     uint8_t *tmp;
      64              : 
      65           16 :     if (is_native) {
      66            8 :         return pmemmove(dest, src, size);
      67              :     }
      68              : 
      69            8 :     tmp = (uint8_t *)pmalloc(size);
      70            8 :     if (tmp == NULL) {
      71            0 :         return NULL;
      72              :     }
      73              : 
      74            8 :     pmemcpy(tmp, src, size);
      75            8 :     bswap_memcpy(dest, tmp, size, elem_sizeof(size));
      76              : 
      77            8 :     pfree(tmp);
      78              : 
      79            8 :     return dest;
      80              : }
      81              : 
      82           12 : static inline int memcmp_common(const void *s1, const void *s2, size_t size, bool is_native)
      83              : {
      84              :     uint8_t *tmp1, *tmp2;
      85              :     size_t elem_size;
      86              :     int result;
      87              : 
      88           12 :     if (is_native) {
      89            6 :         return pmemcmp(s1, s2, size);
      90              :     }
      91              : 
      92            6 :     tmp1 = (uint8_t *)pmalloc(size);
      93            6 :     tmp2 = (uint8_t *)pmalloc(size);
      94            6 :     if (!tmp1 || !tmp2) {
      95            0 :         if (tmp1) {
      96            0 :             pfree(tmp1);
      97              :         }
      98            0 :         if (tmp2) {
      99            0 :             pfree(tmp2);
     100              :         }
     101            0 :         return 0;
     102              :     }
     103              : 
     104            6 :     elem_size = elem_sizeof(size);
     105            6 :     bswap_memcpy(tmp1, s1, size, elem_size);
     106            6 :     bswap_memcpy(tmp2, s2, size, elem_size);
     107              : 
     108            6 :     result = pmemcmp(tmp1, tmp2, size);
     109              : 
     110            6 :     pfree(tmp1);
     111            6 :     pfree(tmp2);
     112              : 
     113            6 :     return result;
     114              : }
     115              : 
     116         1038 : extern void *pino_endianness_memcpy_le2native(void *dest, const void *src, size_t size)
     117              : {
     118         1038 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     119              : }
     120              : 
     121            5 : extern void *pino_endianness_memcpy_be2native(void *dest, const void *src, size_t size)
     122              : {
     123            5 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     124              : }
     125              : 
     126         2019 : extern void *pino_endianness_memcpy_native2le(void *dest, const void *src, size_t size)
     127              : {
     128         2019 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     129              : }
     130              : 
     131            5 : extern void *pino_endianness_memcpy_native2be(void *dest, const void *src, size_t size)
     132              : {
     133            5 :     return memcpy_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     134              : }
     135              : 
     136            4 : extern void *pino_endianness_memmove_le2native(void *dest, const void *src, size_t size)
     137              : {
     138            4 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     139              : }
     140              : 
     141            3 : extern void *pino_endianness_memmove_be2native(void *dest, const void *src, size_t size)
     142              : {
     143            3 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     144              : }
     145              : 
     146            4 : extern void *pino_endianness_memmove_native2le(void *dest, const void *src, size_t size)
     147              : {
     148            4 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_LITTLE));
     149              : }
     150              : 
     151            5 : extern void *pino_endianness_memmove_native2be(void *dest, const void *src, size_t size)
     152              : {
     153            5 :     return memmove_common(dest, src, size, (platform_endianness() == ENDIANNESS_BIG));
     154              : }
     155              : 
     156            3 : extern int pino_endianness_memcmp_le2native(const void *s1, const void *s2, size_t size)
     157              : {
     158            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_LITTLE));
     159              : }
     160              : 
     161            3 : extern int pino_endianness_memcmp_be2native(const void *s1, const void *s2, size_t size)
     162              : {
     163            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_BIG));
     164              : }
     165              : 
     166            3 : extern int pino_endianness_memcmp_native2le(const void *s1, const void *s2, size_t size)
     167              : {
     168            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_LITTLE));
     169              : }
     170              : 
     171            3 : extern int pino_endianness_memcmp_native2be(const void *s1, const void *s2, size_t size)
     172              : {
     173            3 :     return memcmp_common(s1, s2, size, (platform_endianness() == ENDIANNESS_BIG));
     174              : }
        

Generated by: LCOV version 2.0-1