EMAN2
byteorder.h
Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  * 
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  * 
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  * 
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  * 
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  * 
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  * 
00034  * */
00035 
00036 #ifndef eman__byteorder_h__
00037 #define eman__byteorder_h__ 1
00038 
00039 #ifdef _WIN32
00040         #pragma warning(disable:4819)
00041 #endif  //_WIN32
00042 
00043 #include <cstddef>
00044 
00045 namespace EMAN
00046 {
00066         class ByteOrder
00067         {
00068         public:
00069                 static bool is_host_big_endian();
00070 
00075                 static bool is_float_big_endian(float small_number);
00076                 
00077                 
00084                 template < class T > static bool is_data_big_endian(const T * small_num_addr)
00085                 {
00086                         if (!small_num_addr) {
00087                                 return false;
00088                         }
00089 
00090                         bool data_big_endian = false;
00091                         size_t typesize = sizeof(T);
00092                         char *d = (char *) small_num_addr;
00093 
00094                         if (is_host_big_endian()) {
00095                                 data_big_endian = false;
00096                                 for (size_t i = typesize / 2; i < typesize; i++)
00097                                         {
00098                                                 if (d[i] != 0) {
00099                                                         data_big_endian = true;
00100                                                         break;
00101                                                 }
00102                                         }
00103                         }
00104                         else {
00105                                 data_big_endian = true;
00106                                 for (size_t j = 0; j < typesize / 2; j++) {
00107                                         if (d[j] != 0) {
00108                                                 data_big_endian = false;
00109                                                 break;
00110                                         }
00111                                 }
00112                         }
00113 
00114                         return data_big_endian;
00115                 }
00116 
00120                 template < class T > static void become_big_endian(T * data, size_t n = 1)
00121                 {
00122                         if (!is_host_big_endian()) {
00123                                 swap_bytes < T > (data, n);
00124                         }
00125                 }
00126 
00130                 template < class T > static void become_little_endian(T * data, size_t n = 1)
00131                 {
00132                         if (is_host_big_endian()) {
00133                                 swap_bytes < T > (data, n);
00134                         }
00135                 }
00136 
00139                 template < class T > static void swap_bytes(T * data, size_t n = 1)
00140                 {
00141                         unsigned char s;
00142                         size_t p = sizeof(T);
00143                         char *d = (char *) data;
00144 
00145                         if (p > 1) {
00146                                 for (size_t i = 0; i < n; i++, d += p) {
00147                                         for (size_t j = 0; j < p / 2; j++) {
00148                                                 s = d[j];
00149                                                 d[j] = d[p - 1 - j];
00150                                                 d[p - 1 - j] = s;
00151                                         }
00152                                 }
00153                         }
00154                 }
00155 
00156         private:
00157                 static bool is_host_endian_checked;
00158                 static bool host_big_endian;
00159         };
00160 
00161 }
00162 
00163 #endif