1 /****************************************************************************** 2 * $Id$ 3 * 4 * Project: libLAS - http://liblas.org - A BSD library for LAS format data. 5 * Purpose: Endian macros 6 * Author: Mateusz Loskot, mateusz@loskot.net 7 * 8 * This file has been stolen from <boost/endian.hpp> and 9 * modified for libLAS purposes. 10 * 11 * (C) Copyright Mateusz Loskot 2007, mateusz@loskot.net 12 * (C) Copyright Caleb Epstein 2005 13 * (C) Copyright John Maddock 2006 14 * Distributed under the Boost Software License, Version 1.0. 15 * (See accompanying file LICENSE_1_0.txt or copy at 16 * http://www.boost.org/LICENSE_1_0.txt) 17 * 18 * Revision History 19 * 06 Feb 2006 - Initial Revision 20 * 09 Nov 2006 - fixed variant and version bits for v4 guids 21 * 13 Nov 2006 - added serialization 22 * 17 Nov 2006 - added name-based guid creation 23 * 20 Nov 2006 - add fixes for gcc (from Tim Blechmann) 24 * 07 Mar 2007 - converted to header only 25 * 20 Jan 2008 - removed dependency of Boost and modified for libLAS (by Mateusz Loskot) 26 ****************************************************************************** 27 * 28 * Copyright (c) 1997 29 * Silicon Graphics Computer Systems, Inc. 30 * 31 * Permission to use, copy, modify, distribute and sell this software 32 * and its documentation for any purpose is hereby granted without fee, 33 * provided that the above copyright notice appear in all copies and 34 * that both that copyright notice and this permission notice appear 35 * in supporting documentation. Silicon Graphics makes no 36 * representations about the suitability of this software for any 37 * purpose. It is provided "as is" without express or implied warranty. 38 * 39 * 40 * 41 * Copyright notice reproduced from <boost/detail/limits.hpp>, from 42 * which this code was originally taken. 43 * 44 * Modified by Caleb Epstein to use <endian.h> with GNU libc and to 45 * defined the BOOST_ENDIAN macro. 46 ****************************************************************************/ 47 48 #ifndef LIBLAS_DETAIL_ENDIAN_HPP_INCLUDED 49 #define LIBLAS_DETAIL_ENDIAN_HPP_INCLUDED 50 51 // GNU libc offers the helpful header <endian.h> which defines 52 // __BYTE_ORDER 53 54 #if defined (__GLIBC__) 55 # include <endian.h> 56 # if (__BYTE_ORDER == __LITTLE_ENDIAN) 57 # define LIBLAS_LITTLE_ENDIAN 58 # elif (__BYTE_ORDER == __BIG_ENDIAN) 59 # define LIBLAS_BIG_ENDIAN 60 # elif (__BYTE_ORDER == __PDP_ENDIAN) 61 # define LIBLAS_PDP_ENDIAN 62 # else 63 # error Unknown machine endianness detected. 64 # endif 65 # define LIBLAS_BYTE_ORDER __BYTE_ORDER 66 #elif defined(_BIG_ENDIAN) 67 # define LIBLAS_BIG_ENDIAN 68 # define LIBLAS_BYTE_ORDER 4321 69 #elif defined(_LITTLE_ENDIAN) 70 # define LIBLAS_LITTLE_ENDIAN 71 # define LIBLAS_BYTE_ORDER 1234 72 73 // If they're both defined, we're assuming little for now. See http://liblas.org/ticket/133 74 #elif defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) 75 # define LIBLAS_LITTLE_ENDIAN 76 # define LIBLAS_BYTE_ORDER 1234 77 78 #elif defined(__sparc) || defined(__sparc__) \ 79 || defined(_POWER) || defined(__powerpc__) \ 80 || defined(__ppc__) || defined(__hpux) \ 81 || defined(_MIPSEB) || defined(_POWER) \ 82 || defined(__s390__) 83 # define LIBLAS_BIG_ENDIAN 84 # define LIBLAS_BYTE_ORDER 4321 85 #elif defined(__i386__) || defined(__alpha__) \ 86 || defined(__ia64) || defined(__ia64__) \ 87 || defined(_M_IX86) || defined(_M_IA64) \ 88 || defined(_M_ALPHA) || defined(__amd64) \ 89 || defined(__amd64__) || defined(_M_AMD64) \ 90 || defined(__x86_64) || defined(__x86_64__) \ 91 || defined(_M_X64) 92 93 # define LIBLAS_LITTLE_ENDIAN 94 # define LIBLAS_BYTE_ORDER 1234 95 #else 96 # error The file liblas/detail/endian.hpp needs to be set up for your CPU type. 97 #endif 98 99 100 #if defined(LIBLAS_BIG_ENDIAN) 101 # define LIBLAS_SWAP_BYTES(p) \ 102 do { \ 103 char* first = static_cast<char*>(static_cast<void*>(&p)); \ 104 char* last = first + sizeof(p) - 1; \ 105 for(; first < last; ++first, --last) { \ 106 char const x = *last; \ 107 *last = *first; \ 108 *first = x; \ 109 }} while(false) 110 111 # define LIBLAS_SWAP_BYTES_N(p, n) \ 112 do { \ 113 char* first = static_cast<char*>(static_cast<void*>(&p)); \ 114 char* last = first + n - 1; \ 115 for(; first < last; ++first, --last) { \ 116 char const x = *last; \ 117 *last = *first; \ 118 *first = x; \ 119 }} while(false) 120 121 #else 122 # define LIBLAS_SWAP_BYTES(p) do {} while(false) 123 # define LIBLAS_SWAP_BYTES_N(p, n) do {} while(false) 124 #endif // LIBLAS_BIG_ENDIAN 125 126 #endif // LIBLAS_DETAIL_ENDIAN_HPP_INCLUDED 127 128