177 lines
4.8 KiB
C++
177 lines
4.8 KiB
C++
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_BYTE_ORDEREr_KERNEL_1_
|
|
#define DLIB_BYTE_ORDEREr_KERNEL_1_
|
|
|
|
#include "byte_orderer_kernel_abstract.h"
|
|
#include "../algs.h"
|
|
#include "../assert.h"
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
class byte_orderer
|
|
{
|
|
/*!
|
|
INITIAL VALUE
|
|
- if (this machine is little endian) then
|
|
- little_endian == true
|
|
- else
|
|
- little_endian == false
|
|
|
|
CONVENTION
|
|
- host_is_big_endian() == !little_endian
|
|
- host_is_little_endian() == little_endian
|
|
|
|
- if (this machine is little endian) then
|
|
- little_endian == true
|
|
- else
|
|
- little_endian == false
|
|
|
|
|
|
!*/
|
|
|
|
|
|
public:
|
|
|
|
// this is here for backwards compatibility with older versions of dlib.
|
|
typedef byte_orderer kernel_1a;
|
|
|
|
byte_orderer (
|
|
)
|
|
{
|
|
// This will probably never be false but if it is then it means chars are not 8bits
|
|
// on this system. Which is a problem for this object.
|
|
COMPILE_TIME_ASSERT(sizeof(short) >= 2);
|
|
|
|
unsigned long temp = 1;
|
|
unsigned char* ptr = reinterpret_cast<unsigned char*>(&temp);
|
|
if (*ptr == 1)
|
|
little_endian = true;
|
|
else
|
|
little_endian = false;
|
|
}
|
|
|
|
virtual ~byte_orderer (
|
|
){}
|
|
|
|
bool host_is_big_endian (
|
|
) const { return !little_endian; }
|
|
|
|
bool host_is_little_endian (
|
|
) const { return little_endian; }
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
inline void host_to_network (
|
|
T& item
|
|
) const
|
|
{ if (little_endian) flip(item); }
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
inline void network_to_host (
|
|
T& item
|
|
) const { if (little_endian) flip(item); }
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void host_to_big (
|
|
T& item
|
|
) const { if (little_endian) flip(item); }
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void big_to_host (
|
|
T& item
|
|
) const { if (little_endian) flip(item); }
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void host_to_little (
|
|
T& item
|
|
) const { if (!little_endian) flip(item); }
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void little_to_host (
|
|
T& item
|
|
) const { if (!little_endian) flip(item); }
|
|
|
|
|
|
private:
|
|
|
|
template <
|
|
typename T,
|
|
size_t size
|
|
>
|
|
inline void flip (
|
|
T (&array)[size]
|
|
) const
|
|
/*!
|
|
ensures
|
|
- flips the bytes in every element of this array
|
|
!*/
|
|
{
|
|
for (size_t i = 0; i < size; ++i)
|
|
{
|
|
flip(array[i]);
|
|
}
|
|
}
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
inline void flip (
|
|
T& item
|
|
) const
|
|
/*!
|
|
ensures
|
|
- reverses the byte ordering in item
|
|
!*/
|
|
{
|
|
DLIB_ASSERT_HAS_STANDARD_LAYOUT(T);
|
|
|
|
T value;
|
|
|
|
// If you are getting this as an error then you are probably using
|
|
// this object wrong. If you think you aren't then send me (Davis) an
|
|
// email and I'll either set you straight or change/remove this check so
|
|
// your stuff works :)
|
|
COMPILE_TIME_ASSERT(sizeof(T) <= sizeof(long double));
|
|
|
|
// If you are getting a compile error on this line then it means T is
|
|
// a pointer type. It doesn't make any sense to byte swap pointers
|
|
// since they have no meaning outside the context of their own process.
|
|
// So you probably just forgot to dereference that pointer before passing
|
|
// it to this function :)
|
|
COMPILE_TIME_ASSERT(is_pointer_type<T>::value == false);
|
|
|
|
|
|
const size_t size = sizeof(T);
|
|
unsigned char* const ptr = reinterpret_cast<unsigned char*>(&item);
|
|
unsigned char* const ptr_temp = reinterpret_cast<unsigned char*>(&value);
|
|
for (size_t i = 0; i < size; ++i)
|
|
ptr_temp[size-i-1] = ptr[i];
|
|
|
|
item = value;
|
|
}
|
|
|
|
bool little_endian;
|
|
};
|
|
|
|
// make flip not do anything at all for chars
|
|
template <> inline void byte_orderer::flip<char> ( char& ) const {}
|
|
template <> inline void byte_orderer::flip<unsigned char> ( unsigned char& ) const {}
|
|
template <> inline void byte_orderer::flip<signed char> ( signed char& ) const {}
|
|
}
|
|
|
|
#endif // DLIB_BYTE_ORDEREr_KERNEL_1_
|
|
|