LCOV - code coverage report
Current view: top level - source/lib - byte_order.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 49 82 59.8 %
Date: 2023-01-19 00:18:29 Functions: 13 22 59.1 %

          Line data    Source code
       1             : /* Copyright (C) 2020 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : /*
      24             :  * byte order (endianness) support routines.
      25             :  */
      26             : 
      27             : #include "precompiled.h"
      28             : #include "lib/byte_order.h"
      29             : 
      30             : #include "lib/bits.h"
      31             : 
      32             : #include <cstring>
      33             : 
      34             : #ifndef swap16
      35           1 : u16 swap16(const u16 x)
      36             : {
      37           1 :     return (u16)(((x & 0xff) << 8) | (x >> 8));
      38             : }
      39             : #endif
      40             : 
      41             : #ifndef swap32
      42           3 : u32 swap32(const u32 x)
      43             : {
      44           6 :     return (x << 24) |
      45           6 :         (x >> 24) |
      46           3 :         ((x << 8) & 0x00ff0000) |
      47           3 :         ((x >> 8) & 0x0000ff00);
      48             : }
      49             : #endif
      50             : 
      51             : #ifndef swap64
      52           1 : u64 swap64(const u64 x)
      53             : {
      54           1 :     const u32 lo = (u32)(x & 0xFFFFFFFF);
      55           1 :     const u32 hi = (u32)(x >> 32);
      56           1 :     u64 ret = swap32(lo);
      57           1 :     ret <<= 32;
      58             :     // careful: must shift var of type u64, not u32
      59           1 :     ret |= swap32(hi);
      60           1 :     return ret;
      61             : }
      62             : #endif
      63             : 
      64             : 
      65             : //-----------------------------------------------------------------------------
      66             : 
      67             : 
      68        1051 : u16 read_le16(const void* p)
      69             : {
      70             :     u16 n;
      71        1051 :     memcpy(&n, p, sizeof(n));
      72        1051 :     return to_le16(n);
      73             : }
      74             : 
      75         622 : u32 read_le32(const void* p)
      76             : {
      77             :     u32 n;
      78         622 :     memcpy(&n, p, sizeof(n));
      79         622 :     return to_le32(n);
      80             : }
      81             : 
      82         521 : u64 read_le64(const void* p)
      83             : {
      84             :     u64 n;
      85         521 :     memcpy(&n, p, sizeof(n));
      86         521 :     return to_le64(n);
      87             : }
      88             : 
      89             : 
      90           0 : u16 read_be16(const void* p)
      91             : {
      92             :     u16 n;
      93           0 :     memcpy(&n, p, sizeof(n));
      94           0 :     return to_be16(n);
      95             : }
      96             : 
      97           0 : u32 read_be32(const void* p)
      98             : {
      99             :     u32 n;
     100           0 :     memcpy(&n, p, sizeof(n));
     101           0 :     return to_be32(n);
     102             : }
     103             : 
     104           0 : u64 read_be64(const void* p)
     105             : {
     106             :     u64 n;
     107           0 :     memcpy(&n, p, sizeof(n));
     108           0 :     return to_be64(n);
     109             : }
     110             : 
     111             : 
     112           0 : void write_le16(void* p, u16 x)
     113             : {
     114           0 :     u16 n = to_le16(x);
     115           0 :     memcpy(p, &n, sizeof(n));
     116           0 : }
     117             : 
     118           0 : void write_le32(void* p, u32 x)
     119             : {
     120           0 :     u32 n = to_le32(x);
     121           0 :     memcpy(p, &n, sizeof(n));
     122           0 : }
     123             : 
     124           0 : void write_le64(void* p, u64 x)
     125             : {
     126           0 :     u64 n = to_le64(x);
     127           0 :     memcpy(p, &n, sizeof(n));
     128           0 : }
     129             : 
     130             : 
     131           0 : void write_be16(void* p, u16 x)
     132             : {
     133           0 :     u16 n = to_be16(x);
     134           0 :     memcpy(p, &n, sizeof(n));
     135           0 : }
     136             : 
     137           0 : void write_be32(void* p, u32 x)
     138             : {
     139           0 :     u32 n = to_be32(x);
     140           0 :     memcpy(p, &n, sizeof(n));
     141           0 : }
     142             : 
     143           0 : void write_be64(void* p, u64 x)
     144             : {
     145           0 :     u64 n = to_be64(x);
     146           0 :     memcpy(p, &n, sizeof(n));
     147           0 : }
     148             : 
     149             : 
     150           9 : u64 movzx_le64(const u8* p, size_t size_bytes)
     151             : {
     152           9 :     u64 number = 0;
     153          40 :     for(size_t i = 0; i < std::min(size_bytes, (size_t)8u); i++)
     154          31 :         number |= ((u64)p[i]) << (i*8);
     155             : 
     156           9 :     return number;
     157             : }
     158             : 
     159           9 : u64 movzx_be64(const u8* p, size_t size_bytes)
     160             : {
     161           9 :     u64 number = 0;
     162          40 :     for(size_t i = 0; i < std::min(size_bytes, (size_t)8u); i++)
     163             :     {
     164          31 :         number <<= 8;
     165          31 :         number |= p[i];
     166             :     }
     167             : 
     168           9 :     return number;
     169             : }
     170             : 
     171             : 
     172           8 : static inline i64 SignExtend(u64 bits, size_t size_bytes)
     173             : {
     174             :     // no point in sign-extending if >= 8 bytes were requested
     175           8 :     if(size_bytes < 8)
     176             :     {
     177           6 :         const u64 sign_bit = Bit<u64>((size_bytes*8)-1);
     178             : 
     179             :         // number would be negative in the smaller type,
     180             :         // so sign-extend, i.e. set all more significant bits.
     181           6 :         if(bits & sign_bit)
     182             :         {
     183           3 :             const u64 valid_bit_mask = (sign_bit+sign_bit)-1;
     184           3 :             bits |= ~valid_bit_mask;
     185             :         }
     186             :     }
     187             : 
     188           8 :     const i64 number = static_cast<i64>(bits);
     189           8 :     return number;
     190             : }
     191             : 
     192           4 : i64 movsx_le64(const u8* p, size_t size_bytes)
     193             : {
     194           4 :     const u64 number = movzx_le64(p, size_bytes);
     195           4 :     return SignExtend(number, size_bytes);
     196             : }
     197             : 
     198           4 : i64 movsx_be64(const u8* p, size_t size_bytes)
     199             : {
     200           4 :     const u64 number = movzx_be64(p, size_bytes);
     201           4 :     return SignExtend(number, size_bytes);
     202           3 : }

Generated by: LCOV version 1.13