LCOV - code coverage report
Current view: top level - common/utils - copybinary_support.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 51 66 77.3 %
Date: 2024-10-03 20:03:20 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #ifndef COPYBINARY_SUPPORT_H
      14             : #define COPYBINARY_SUPPORT_H
      15             : 
      16             : #include "copybinary.h"
      17             : 
      18             : // According to Godbolt, these code sequences are recognized by
      19             : // GCC at least back to 6.2 and Clang at least back to 6.0.0.
      20             : // I didn't check earlier ones.
      21             : // They properly use byte swapping instructions.
      22             : // MSVC doesn't recognize it but that's no problem because we will
      23             : // not ever use it for big endian platforms.
      24             : 
      25             : // First some macros that can be used a expressions:
      26             : //    uint16_t swapped = copy_binary_byteswap16(value);
      27             : 
      28             : 
      29             : #ifdef _MSC_VER
      30             : 
      31             : static inline uint16_t
      32             : copy_binary_byteswap16(uint16_t value) {
      33             :         return _byteswap_ushort(value);
      34             : }
      35             : 
      36             : static inline uint32_t
      37             : copy_binary_byteswap32(uint32_t value) {
      38             :         return _byteswap_ulong(value);
      39             : }
      40             : 
      41             : static inline uint64_t
      42             : copy_binary_byteswap64(uint64_t value) {
      43             :         return _byteswap_uint64(value);
      44             : }
      45             : 
      46             : #else
      47             : 
      48             : static inline uint16_t
      49     5000022 : copy_binary_byteswap16(uint16_t value) {
      50     5000022 :         return
      51     5000018 :                 ((value & 0xFF00u) >>  8u) |
      52             :                 ((value & 0x00FFu) <<  8u)
      53             :                 ;
      54             : }
      55             : 
      56             : static inline uint32_t
      57    14000047 : copy_binary_byteswap32(uint32_t value) {
      58    14000047 :         return
      59    14000047 :                 ((value & 0xFF000000u) >> 24u) |
      60    14000047 :                 ((value & 0x00FF0000u) >>  8u) |
      61    14000047 :                 ((value & 0x0000FF00u) <<  8u) |
      62    14000045 :                 ((value & 0x000000FFu) << 24u)
      63             :                 ;
      64             : }
      65             : 
      66             : static inline uint64_t
      67    15000033 : copy_binary_byteswap64(uint64_t value) {
      68    15000033 :         return
      69    15000033 :                 ((value & 0xFF00000000000000u) >> 56u) |
      70    15000033 :                 ((value & 0x00FF000000000000u) >> 40u) |
      71    15000033 :                 ((value & 0x0000FF0000000000u) >> 24u) |
      72    15000033 :                 ((value & 0x000000FF00000000u) >>  8u) |
      73    15000033 :                 ((value & 0x00000000FF000000u) <<  8u) |
      74    15000033 :                 ((value & 0x0000000000FF0000u) << 24u) |
      75    15000033 :                 ((value & 0x000000000000FF00u) << 40u) |
      76    15000033 :                 ((value & 0x00000000000000FFu) << 56u)
      77             :                 ;
      78             : }
      79             : 
      80             : #endif
      81             : 
      82             : #ifdef HAVE_HGE
      83             : static inline
      84           6 : uhge copy_binary_byteswap128(uhge value) {
      85           6 :         uint64_t lo = (uint64_t) value;
      86           6 :         uint64_t hi = (uint64_t) (value >> 64);
      87           6 :         uhge swapped_lo = (uhge)copy_binary_byteswap64(lo);
      88           6 :         uhge swapped_hi = (uhge)copy_binary_byteswap64(hi);
      89           6 :         return swapped_hi | (swapped_lo << 64);
      90             : }
      91             : #endif
      92             : 
      93             : static inline copy_binary_date
      94           4 : copy_binary_byteswap_date(copy_binary_date value)
      95             : {
      96           4 :         return (copy_binary_date) {
      97             :                 .day = value.day,
      98             :                 .month = value.month,
      99           2 :                 .year = copy_binary_byteswap16(value.year),
     100             :         };
     101             : }
     102             : 
     103             : static inline copy_binary_time
     104           2 : copy_binary_byteswap_time(copy_binary_time value)
     105             : {
     106           2 :         return (copy_binary_time) {
     107           2 :                 .ms = copy_binary_byteswap32(value.ms),
     108           2 :                 .seconds = value.seconds,
     109           2 :                 .minutes = value.minutes,
     110           2 :                 .hours = value.hours,
     111           2 :                 .padding = value.padding,
     112             :         };
     113             : }
     114             : 
     115             : static inline copy_binary_timestamp
     116           2 : copy_binary_byteswap_timestamp(copy_binary_timestamp value)
     117             : {
     118           2 :         return (copy_binary_timestamp) {
     119           2 :                 .time = copy_binary_byteswap_time(value.time),
     120           2 :                 .date = copy_binary_byteswap_date(value.date),
     121             :         };
     122             : }
     123             : 
     124             : 
     125             : 
     126             : 
     127             : // These macros are used to convert a value in-place.
     128             : // This makes it possible to also convert timestamp structs.
     129             : 
     130             : static inline void
     131     1000012 : copy_binary_convert16(void *p)
     132             : {
     133     1000012 :         uint16_t *pp = (uint16_t*)p;
     134     1000012 :         *pp = copy_binary_byteswap16(*pp);
     135     1000012 : }
     136             : 
     137             : static inline void
     138     2000012 : copy_binary_convert32(void *p)
     139             : {
     140     2000012 :         uint32_t *pp = (uint32_t*)p;
     141     2000012 :         *pp = copy_binary_byteswap32(*pp);
     142     2000012 : }
     143             : 
     144             : static inline void
     145     7000012 : copy_binary_convert64(void *p)
     146             : {
     147     7000012 :         uint64_t *pp = (uint64_t*)p;
     148     7000012 :         *pp = copy_binary_byteswap64(*pp);
     149     7000012 : }
     150             : 
     151             : #ifdef HAVE_HGE
     152             : static inline void
     153           0 : copy_binary_convert128(void *p)
     154             : {
     155           0 :         uhge *pp = (uhge*)p;
     156           0 :         *pp = copy_binary_byteswap128(*pp);
     157           0 : }
     158             : #endif
     159             : 
     160             : static inline void
     161           0 : copy_binary_convert_date(void *p)
     162             : {
     163           0 :         copy_binary_date *pp = (copy_binary_date*)p;
     164           0 :         copy_binary_convert16(&pp->year);
     165             : }
     166             : 
     167             : 
     168             : static inline void
     169           0 : copy_binary_convert_time(void *p)
     170             : {
     171           0 :         copy_binary_time *pp = (copy_binary_time*)p;
     172           0 :         copy_binary_convert32(&pp->ms);
     173             : }
     174             : 
     175             : static inline void
     176           0 : copy_binary_convert_timestamp(void *p)
     177             : {
     178           0 :         copy_binary_timestamp *pp = (copy_binary_timestamp*)p;
     179           0 :         copy_binary_convert_date(&pp->date);
     180           0 :         copy_binary_convert_time(&pp->time);
     181           0 : }
     182             : 
     183             : #endif

Generated by: LCOV version 1.14