PageRenderTime 14ms CodeModel.GetById 2ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

/mordor/endian.h

http://github.com/mozy/mordor
C Header | 173 lines | 141 code | 24 blank | 8 comment | 16 complexity | 8f0e16832205d276ba005570f9a48cc6 MD5 | raw file
  1#ifndef __MORDOR_ENDIAN_H__
  2#define __MORDOR_ENDIAN_H__
  3// Copyright (c) 2009 - Mozy, Inc.
  4
  5#include <boost/utility/enable_if.hpp>
  6
  7#include "version.h"
  8
  9#define MORDOR_LITTLE_ENDIAN 1
 10#define MORDOR_BIG_ENDIAN 2
 11
 12#ifdef WINDOWS
 13#include <stdlib.h>
 14#elif defined(OSX)
 15#include <libkern/OSByteOrder.h>
 16#include <stdint.h>
 17#include <sys/_endian.h>
 18#elif defined(FREEBSD)
 19#include <stdint.h>
 20#include <sys/endian.h>
 21#else
 22#include <byteswap.h>
 23#include <stdint.h>
 24#endif
 25
 26namespace Mordor {
 27
 28#ifdef WINDOWS
 29
 30template <class T>
 31typename boost::enable_if_c<sizeof(T) == sizeof(unsigned __int64), T>::type
 32byteswap(T value)
 33{
 34    return (T)_byteswap_uint64((unsigned __int64)value);
 35}
 36template <class T>
 37typename boost::enable_if_c<sizeof(T) == sizeof(unsigned long), T>::type
 38byteswap(T value)
 39{
 40    return (T)_byteswap_ulong((unsigned long)value);
 41}
 42template <class T>
 43typename boost::enable_if_c<sizeof(T) == sizeof(unsigned short), T>::type
 44byteswap(T value)
 45{
 46    return (T)_byteswap_ushort((unsigned short)value);
 47}
 48
 49#define MORDOR_BYTE_ORDER MORDOR_LITTLE_ENDIAN
 50
 51#elif defined(OSX)
 52
 53template <class T>
 54typename boost::enable_if_c<sizeof(T) == sizeof(uint64_t), T>::type
 55byteswap(T value)
 56{
 57    return (T)_OSSwapInt64((uint64_t)value);
 58}
 59template <class T>
 60typename boost::enable_if_c<sizeof(T) == sizeof(uint32_t), T>::type
 61byteswap(T value)
 62{
 63    return (T)_OSSwapInt32((uint32_t)value);
 64}
 65template <class T>
 66typename boost::enable_if_c<sizeof(T) == sizeof(uint16_t), T>::type
 67byteswap(T value)
 68{
 69    return (T)_OSSwapInt16((uint16_t)value);
 70}
 71
 72#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
 73#error Do not know the endianess of this architecture
 74#endif
 75
 76#ifdef __BIG_ENDIAN__
 77#define MORDOR_BYTE_ORDER MORDOR_BIG_ENDIAN
 78#else
 79#define MORDOR_BYTE_ORDER MORDOR_LITTLE_ENDIAN
 80#endif
 81
 82#elif defined(FREEBSD)
 83
 84template <class T>
 85typename boost::enable_if_c<sizeof(T) == sizeof(uint64_t), T>::type
 86byteswap(T value)
 87{
 88    return (T)bswap64((uint64_t)value);
 89}
 90template <class T>
 91typename boost::enable_if_c<sizeof(T) == sizeof(uint32_t), T>::type
 92byteswap(T value)
 93{
 94    return (T)bswap32((uint32_t)value);
 95}
 96template <class T>
 97typename boost::enable_if_c<sizeof(T) == sizeof(uint16_t), T>::type
 98byteswap(T value)
 99{
100    return (T)bswap16((uint16_t)value);
101}
102
103#if _BYTE_ORDER == _BIG_ENDIAN
104#define MORDOR_BYTE_ORDER MORDOR_BIG_ENDIAN
105#else
106#define MORDOR_BYTE_ORDER MORDOR_LITTLE_ENDIAN
107#endif
108
109#else
110
111template <class T>
112typename boost::enable_if_c<sizeof(T) == sizeof(uint64_t), T>::type
113byteswap(T value)
114{
115    return (T)bswap_64((uint64_t)value);
116}
117template <class T>
118typename boost::enable_if_c<sizeof(T) == sizeof(uint32_t), T>::type
119byteswap(T value)
120{
121    return (T)bswap_32((uint32_t)value);
122}
123template <class T>
124typename boost::enable_if_c<sizeof(T) == sizeof(uint16_t), T>::type
125byteswap(T value)
126{
127    return (T)bswap_16((uint16_t)value);
128}
129
130#if BYTE_ORDER == BIG_ENDIAN
131#define MORDOR_BYTE_ORDER MORDOR_BIG_ENDIAN
132#else
133#define MORDOR_BYTE_ORDER MORDOR_LITTLE_ENDIAN
134#endif
135
136#endif
137
138#if MORDOR_BYTE_ORDER == MORDOR_BIG_ENDIAN
139template <class T>
140T byteswapOnLittleEndian(T t)
141{
142    return t;
143}
144
145template <class T>
146T byteswapOnBigEndian(T t)
147{
148    return byteswap(t);
149}
150#else
151/// byteswap only when running on a little endian platform
152///
153/// On big endian platforms, it's a no op.  This is the equivalent of
154/// htonX/ntohX
155template <class T>
156T byteswapOnLittleEndian(T t)
157{
158    return byteswap(t);
159}
160
161/// byteswap only when running on a big endian platform
162///
163/// On little endian platforms, it's a no op.
164template <class T>
165T byteswapOnBigEndian(T t)
166{
167    return t;
168}
169#endif
170
171}
172
173#endif