Home | History | Annotate | Download | only in lib
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 
     23 #include "curl_setup.h"
     24 
     25 #include "curl_endian.h"
     26 
     27 /*
     28  * Curl_read16_le()
     29  *
     30  * This function converts a 16-bit integer from the little endian format, as
     31  * used in the incoming package to whatever endian format we're using
     32  * natively.
     33  *
     34  * Parameters:
     35  *
     36  * buf      [in]     - A pointer to a 2 byte buffer.
     37  *
     38  * Returns the integer.
     39  */
     40 unsigned short Curl_read16_le(const unsigned char *buf)
     41 {
     42   return (unsigned short)(((unsigned short)buf[0]) |
     43                           ((unsigned short)buf[1] << 8));
     44 }
     45 
     46 /*
     47  * Curl_read32_le()
     48  *
     49  * This function converts a 32-bit integer from the little endian format, as
     50  * used in the incoming package to whatever endian format we're using
     51  * natively.
     52  *
     53  * Parameters:
     54  *
     55  * buf      [in]     - A pointer to a 4 byte buffer.
     56  *
     57  * Returns the integer.
     58  */
     59 unsigned int Curl_read32_le(const unsigned char *buf)
     60 {
     61   return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
     62          ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
     63 }
     64 
     65 #if (CURL_SIZEOF_CURL_OFF_T > 4)
     66 /*
     67  * Curl_read64_le()
     68  *
     69  * This function converts a 64-bit integer from the little endian format, as
     70  * used in the incoming package to whatever endian format we're using
     71  * natively.
     72  *
     73  * Parameters:
     74  *
     75  * buf      [in]     - A pointer to a 8 byte buffer.
     76  *
     77  * Returns the integer.
     78  */
     79 #if defined(HAVE_LONGLONG)
     80 unsigned long long Curl_read64_le(const unsigned char *buf)
     81 {
     82   return ((unsigned long long)buf[0]) |
     83          ((unsigned long long)buf[1] << 8) |
     84          ((unsigned long long)buf[2] << 16) |
     85          ((unsigned long long)buf[3] << 24) |
     86          ((unsigned long long)buf[4] << 32) |
     87          ((unsigned long long)buf[5] << 40) |
     88          ((unsigned long long)buf[6] << 48) |
     89          ((unsigned long long)buf[7] << 56);
     90 }
     91 #else
     92 unsigned __int64 Curl_read64_le(const unsigned char *buf)
     93 {
     94   return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
     95          ((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
     96          ((unsigned __int64)buf[4] << 32) | ((unsigned __int64)buf[5] << 40) |
     97          ((unsigned __int64)buf[6] << 48) | ((unsigned __int64)buf[7] << 56);
     98 }
     99 #endif
    100 
    101 #endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
    102 
    103 /*
    104  * Curl_read16_be()
    105  *
    106  * This function converts a 16-bit integer from the big endian format, as
    107  * used in the incoming package to whatever endian format we're using
    108  * natively.
    109  *
    110  * Parameters:
    111  *
    112  * buf      [in]     - A pointer to a 2 byte buffer.
    113  *
    114  * Returns the integer.
    115  */
    116 unsigned short Curl_read16_be(const unsigned char *buf)
    117 {
    118   return (unsigned short)(((unsigned short)buf[0] << 8) |
    119                           ((unsigned short)buf[1]));
    120 }
    121 
    122 /*
    123  * Curl_read32_be()
    124  *
    125  * This function converts a 32-bit integer from the big endian format, as
    126  * used in the incoming package to whatever endian format we're using
    127  * natively.
    128  *
    129  * Parameters:
    130  *
    131  * buf      [in]     - A pointer to a 4 byte buffer.
    132  *
    133  * Returns the integer.
    134  */
    135 unsigned int Curl_read32_be(const unsigned char *buf)
    136 {
    137   return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
    138          ((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
    139 }
    140 
    141 #if (CURL_SIZEOF_CURL_OFF_T > 4)
    142 /*
    143  * Curl_read64_be()
    144  *
    145  * This function converts a 64-bit integer from the big endian format, as
    146  * used in the incoming package to whatever endian format we're using
    147  * natively.
    148  *
    149  * Parameters:
    150  *
    151  * buf      [in]     - A pointer to a 8 byte buffer.
    152  *
    153  * Returns the integer.
    154  */
    155 #if defined(HAVE_LONGLONG)
    156 unsigned long long Curl_read64_be(const unsigned char *buf)
    157 {
    158   return ((unsigned long long)buf[0] << 56) |
    159          ((unsigned long long)buf[1] << 48) |
    160          ((unsigned long long)buf[2] << 40) |
    161          ((unsigned long long)buf[3] << 32) |
    162          ((unsigned long long)buf[4] << 24) |
    163          ((unsigned long long)buf[5] << 16) |
    164          ((unsigned long long)buf[6] << 8) |
    165          ((unsigned long long)buf[7]);
    166 }
    167 #else
    168 unsigned __int64 Curl_read64_be(const unsigned char *buf)
    169 {
    170   return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
    171          ((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
    172          ((unsigned __int64)buf[4] << 24) | ((unsigned __int64)buf[5] << 16) |
    173          ((unsigned __int64)buf[6] << 8) | ((unsigned __int64)buf[7]);
    174 }
    175 #endif
    176 
    177 #endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
    178 
    179 /*
    180  * Curl_write16_le()
    181  *
    182  * This function converts a 16-bit integer from the native endian format,
    183  * to little endian format ready for sending down the wire.
    184  *
    185  * Parameters:
    186  *
    187  * value    [in]     - The 16-bit integer value.
    188  * buffer   [in]     - A pointer to the output buffer.
    189  */
    190 void Curl_write16_le(const short value, unsigned char *buffer)
    191 {
    192   buffer[0] = (char)(value & 0x00FF);
    193   buffer[1] = (char)((value & 0xFF00) >> 8);
    194 }
    195 
    196 /*
    197  * Curl_write32_le()
    198  *
    199  * This function converts a 32-bit integer from the native endian format,
    200  * to little endian format ready for sending down the wire.
    201  *
    202  * Parameters:
    203  *
    204  * value    [in]     - The 32-bit integer value.
    205  * buffer   [in]     - A pointer to the output buffer.
    206  */
    207 void Curl_write32_le(const int value, unsigned char *buffer)
    208 {
    209   buffer[0] = (char)(value & 0x000000FF);
    210   buffer[1] = (char)((value & 0x0000FF00) >> 8);
    211   buffer[2] = (char)((value & 0x00FF0000) >> 16);
    212   buffer[3] = (char)((value & 0xFF000000) >> 24);
    213 }
    214 
    215 #if (CURL_SIZEOF_CURL_OFF_T > 4)
    216 /*
    217  * Curl_write64_le()
    218  *
    219  * This function converts a 64-bit integer from the native endian format,
    220  * to little endian format ready for sending down the wire.
    221  *
    222  * Parameters:
    223  *
    224  * value    [in]     - The 64-bit integer value.
    225  * buffer   [in]     - A pointer to the output buffer.
    226  */
    227 #if defined(HAVE_LONGLONG)
    228 void Curl_write64_le(const long long value, unsigned char *buffer)
    229 #else
    230 void Curl_write64_le(const __int64 value, unsigned char *buffer)
    231 #endif
    232 {
    233   Curl_write32_le((int)value, buffer);
    234   Curl_write32_le((int)(value >> 32), buffer + 4);
    235 }
    236 #endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
    237