emsApplication/sdk/include/zmqpp/inet.hpp

191 lines
4.4 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file is part of zmqpp.
* Copyright (c) 2011-2015 Contributors as noted in the AUTHORS file.
*/
/**
* \file
*
* \date 10 Aug 2011
* \author Ben Gray (\@benjamg)
*/
#ifndef ZMQPP_INET_HPP_
#define ZMQPP_INET_HPP_
#include <utility>
#include <cassert>
#include <cstdint>
/** \todo cross-platform version of including headers. */
// We get htons and htonl from here
#ifdef _WIN32
#include <WinSock2.h>
#else
#include <netinet/in.h>
#endif
#include "compatibility.hpp"
namespace zmqpp
{
/*!
* \brief Possible byte order types.
*
* An enumeration of all the known order types, all two of them.
* There is also an entry for unknown which is just used as a default.
*/
ZMQPP_COMPARABLE_ENUM order {
big_endian, /*!< byte order is big endian */
little_endian /*!< byte order is little endian */
};
/*!
* Common code for the 64bit versions of htons/htons and ntohs/ntohl
*
* As htons and ntohs (or htonl and ntohs) always just do the same thing, ie
* swap bytes if the host order differs from network order or otherwise don't
* do anything, it seemed silly to type the code twice.
*
* \note This code assumes network order is always big endian. Which it is.
* \note The host endian is only checked once and afterwards assumed to remain
* the same.
*
* \param value_to_check unsigned 64 bit integer to swap
* \return swapped (or not) unsigned 64 bit integer
*/
inline uint64_t swap_if_needed(uint64_t const value_to_check)
{
static order host_order = (htonl(42) == 42) ? order::big_endian : order::little_endian;
if (order::big_endian == host_order)
{
return value_to_check;
}
union {
uint64_t integer;
uint8_t bytes[8];
} value { value_to_check };
std::swap(value.bytes[0], value.bytes[7]);
std::swap(value.bytes[1], value.bytes[6]);
std::swap(value.bytes[2], value.bytes[5]);
std::swap(value.bytes[3], value.bytes[4]);
return value.integer;
}
/*!
* 64 bit version of the htons/htonl
*
* I've used the name htonll to try and keep with the htonl naming scheme.
* We do not define this function if the macro `htonll` exists.
*
* \param hostlonglong unsigned 64 bit host order integer
* \return unsigned 64 bit network order integer
*/
#ifndef htonll
inline uint64_t htonll(uint64_t const hostlonglong)
{
return zmqpp::swap_if_needed(hostlonglong);
}
#endif
/*!
* 64 bit version of the ntohs/ntohl
*
* I've used the name htonll to try and keep with the htonl naming scheme.
* We do not define this function if the macro `ntohll` exists.
*
* \param networklonglong unsigned 64 bit network order integer
* \return unsigned 64 bit host order integer
*/
#ifndef ntohll
inline uint64_t ntohll(uint64_t const networklonglong)
{
return zmqpp::swap_if_needed(networklonglong);
}
#endif
/*!
* floating point version of the htons/htonl
*
* \param value host order floating point
* \returns network order floating point
*/
inline float htonf(float value)
{
assert(sizeof(float) == sizeof(uint32_t));
uint32_t temp;
memcpy(&temp, &value, sizeof(uint32_t));
temp = htonl( temp );
memcpy(&value, &temp, sizeof(uint32_t));
return value;
}
/*!
* floating point version of the ntohs/ntohl
*
* \param value network order float
* \returns host order float
*/
inline float ntohf(float value)
{
assert(sizeof(float) == sizeof(uint32_t));
uint32_t temp;
memcpy(&temp, &value, sizeof(uint32_t));
temp = ntohl( temp );
memcpy(&value, &temp, sizeof(uint32_t));
return value;
}
/*!
* double precision floating point version of the htons/htonl
*
* \param value host order double precision floating point
* \returns network order double precision floating point
*/
inline double htond(double value)
{
assert(sizeof(double) == sizeof(uint64_t));
uint64_t temp;
memcpy(&temp, &value, sizeof(uint64_t));
temp = htonll(temp);
memcpy(&value, &temp, sizeof(uint64_t));
return value;
}
/*!
* double precision floating point version of the ntohs/ntohl
*
* \param value network order double precision floating point
* \returns host order double precision floating point
*/
inline double ntohd(double value)
{
assert(sizeof(double) == sizeof(uint64_t));
uint64_t temp;
memcpy(&temp, &value, sizeof(uint64_t));
temp = ntohll(temp);
memcpy(&value, &temp, sizeof(uint64_t));
return value;
}
}
#endif /* INET_HPP_ */