BugInTheSYS

Static class member function pointer bitchingness.

Oct 21st, 2011
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.38 KB | None | 0 0
  1. //***************
  2. // "endian.h"   *
  3. //***************
  4.  
  5. enum endianness_t {
  6.   BIG_ENDIAN,
  7.   LITTLE_ENDIAN
  8. };
  9.  
  10. // I could make this a namespace if those had private and public, since this class has only static members.
  11. class Endian {
  12. private:
  13.   // Gets the endianness of the system
  14.   static const endianness_t _SysEndian( void );
  15.   static endianness_t _endian;
  16.  
  17.   static short  SwapShort( const short nValue );
  18.   static short  KeepShort( const short nValue );
  19.   static int    SwapInt( const int nValue );
  20.   static int    KeepInt( const int nValue );
  21.   static long   SwapLong( const long nValue );
  22.   static long   KeepLong( const long nValue );
  23.   static float  SwapFloat( const float fValue );
  24.   static float  KeepFloat( const float fValue );
  25.   static double SwapDouble( const double fValue );
  26.   static double KeepDouble( const double fValue );
  27.   static void   SwapRevBytes( void *pBase, const unsigned int nUnitSize, int nUnitCount );
  28.   static void   KeepRevBytes( void *pBase, const unsigned int nUnitSize, int nUnitCount );
  29.  
  30. public:
  31.   static const endianness_t *sysEndian;
  32.  
  33.   static void Init( void );
  34.  
  35.   // Method pointers to convert from little/big endian to the system's endian. Call Init() before use - that's where they're set, just to avoid branching.
  36.   static short  ( *_BigShort )( const short nValue );
  37.   static short  ( *_LittleShort )( const short nValue );
  38.   static int    ( *_BigInt )( const int nValue );
  39.   static int    ( *_LittleInt )( const int nValue );
  40.   static long   ( *_BigLong )( const long nValue );
  41.   static long   ( *_LittleLong )( const long nValue );
  42.   static float  ( *_BigFloat )( const float fValue );
  43.   static float  ( *_LittleFloat )( const float fValue );
  44.   static double ( *_BigDouble )( const double fValue );
  45.   static double ( *_LittleDouble )( const double fValue );
  46.   static void   ( *_BigRevBytes )( void *pBase, const unsigned int nUnitSize, int nUnitCount );
  47.   static void   ( *_LittleRevBytes )( void *pBase, const unsigned int nUnitSize, int nUnitCount );
  48. };
  49.  
  50. //***************
  51. // "endian.cpp" *
  52. //***************
  53.  
  54. #include "endian.h"
  55.  
  56. short  BigShort( const short nValue ) { return Endian::_BigShort( nValue ); }
  57. short  LittleShort( const short nValue ) { return Endian::_LittleShort( nValue ); }
  58. int    BigInt( const int nValue ) { return Endian::_BigInt( nValue ); }
  59. int    LittleInt( const int nValue ) { return Endian::_LittleInt( nValue ); }
  60. long   BigLong( const long nValue ) { return Endian::_BigLong( nValue ); }
  61. long   LittleLong( const long nValue ) { return Endian::_LittleLong( nValue ); }
  62. float  BigFloat( const float fValue ) { return Endian::_BigFloat( fValue ); }
  63. float  LittleFloat( const float fValue ) { return Endian::_LittleFloat( fValue ); }
  64. double BigDouble( const double fValue ) { return Endian::_BigDouble( fValue ); }
  65. double LittleDouble( const double fValue ) { return Endian::_LittleDouble( fValue ); }
  66. void   BigRevBytes( void *pBase, const unsigned int nUnitSize, int nUnitCount ) { Endian::_BigRevBytes( pBase, nUnitSize, nUnitCount ); }
  67. void   LittleRevBytes( void *pBase, const unsigned int nUnitSize, int nUnitCount ) { Endian::_LittleRevBytes( pBase, nUnitSize, nUnitCount ); }
  68.  
  69. /*
  70. ====================
  71. SysEndian
  72.  
  73.   Returns a value indicating the system's endianness.
  74. ====================
  75. */
  76. const endianness_t Endian::_SysEndian( void ) {
  77.   unsigned char endianTest[] = { 1, 0 };
  78.  
  79.   if ( *( short * )endianTest == 1 ) {
  80.     return LITTLE_ENDIAN;
  81.   } else {
  82.     return BIG_ENDIAN;
  83.   }
  84. }
  85.  
  86. /*
  87. ====================
  88. Init
  89.  
  90.   Sets up variables for use of the member functions/variables.
  91. ====================
  92. */
  93. void Endian::Init( void ) {
  94.   _endian = _SysEndian();
  95.   sysEndian = &_endian;
  96.  
  97.   if( _endian == LITTLE_ENDIAN ) {
  98.     // likely an x86 machine
  99.     _BigShort = SwapShort;
  100.     _LittleShort = KeepShort;
  101.     _BigInt = SwapInt;
  102.     _LittleInt = KeepInt;
  103.     _BigLong = SwapLong;
  104.     _LittleLong = KeepLong;
  105.     _BigFloat = SwapFloat;
  106.     _LittleFloat = KeepFloat;
  107.     _BigDouble = SwapDouble;
  108.     _LittleDouble = KeepDouble;
  109.     _BigRevBytes = SwapRevBytes;
  110.     _LittleRevBytes = KeepRevBytes;
  111.   } else {
  112.     // mac or what do I know
  113.     _BigShort = KeepShort;
  114.     _LittleShort = SwapShort;
  115.     _BigInt = KeepInt;
  116.     _LittleInt = SwapInt;
  117.     _BigLong = KeepLong;
  118.     _LittleLong = SwapLong;
  119.     _BigFloat = KeepFloat;
  120.     _LittleFloat = SwapFloat;
  121.     _BigDouble = KeepDouble;
  122.     _LittleDouble = SwapDouble;
  123.     _BigRevBytes = KeepRevBytes;
  124.     _LittleRevBytes = SwapRevBytes;
  125.   }
  126. }
  127.  
  128. /*
  129. ====================
  130. SwapShort
  131. ====================
  132. */
  133. short Endian::SwapShort( const short nValue ) {
  134.   unsigned char FirstByte, SecondByte;
  135.  
  136.     SecondByte = nValue & 255;
  137.     FirstByte  = ( nValue >> 8 ) & 255;
  138.  
  139.     return ( SecondByte << 8 ) + FirstByte;
  140. }
  141.  
  142. /*
  143. ====================
  144. KeepShort
  145. ====================
  146. */
  147. short Endian::KeepShort( const short nValue ) {
  148.   return nValue;
  149. }
  150.  
  151. /*
  152. ====================
  153. SwapInt
  154. ====================
  155. */
  156. int Endian::SwapInt( const int nValue ) {
  157.   unsigned char FirstByte, SecondByte, ThirdByte, FourthByte;
  158.  
  159.     FourthByte = ( nValue ) & 255;
  160.   ThirdByte  = ( nValue >> 8 ) & 255;
  161.   SecondByte = ( nValue >> 16 ) & 255;
  162.     FirstByte  = ( nValue >> 24 ) & 255;
  163.  
  164.     return ( ( int ) FourthByte << 24 ) + ( ( int ) ThirdByte << 16 ) + ( ( int ) SecondByte << 8 ) + FirstByte;
  165. }
  166.  
  167. /*
  168. ====================
  169. KeepInt
  170. ====================
  171. */
  172. int Endian::KeepInt( const int nValue ) {
  173.   return nValue;
  174. }
  175.  
  176. /*
  177. ====================
  178. SwapLong
  179. ====================
  180. */
  181. long Endian::SwapLong( const long nValue ) {
  182.   unsigned char FirstByte, SecondByte, ThirdByte, FourthByte, FifthByte, SixthByte, SeventhByte, EighthByte;
  183.  
  184.     EighthByte  = ( nValue ) & 255;
  185.   SeventhByte = ( nValue >> 8 ) & 255;
  186.   SixthByte   = ( nValue >> 16 ) & 255;
  187.     FifthByte   = ( nValue >> 24 ) & 255;
  188.   FourthByte  = ( nValue >> 32 ) & 255;
  189.   ThirdByte   = ( nValue >> 40 ) & 255;
  190.   SecondByte  = ( nValue >> 48 ) & 255;
  191.   FirstByte   = ( nValue >> 56 ) & 255;
  192.  
  193.     return ( ( long ) EighthByte << 56 )
  194.          + ( ( long ) SeventhByte << 48 )
  195.          + ( ( long ) SixthByte << 40 )
  196.          + ( ( long ) FifthByte << 32 )
  197.          + ( ( long ) FourthByte << 24 )
  198.          + ( ( long ) ThirdByte << 16 )
  199.          + ( ( long ) SecondByte << 8 )
  200.          + FirstByte;
  201. }
  202.  
  203. /*
  204. ====================
  205. KeepLong
  206. ====================
  207. */
  208. long Endian::KeepLong( const long nValue ) {
  209.   return nValue;
  210. }
  211.  
  212. /*
  213. ====================
  214. SwapFloat
  215. ====================
  216. */
  217. float Endian::SwapFloat( const float fValue ) {
  218.   union {
  219.     float f;
  220.     unsigned char b[ 4 ];
  221.   } Data1, Data2;
  222.  
  223.   Data1.f = fValue;
  224.   Data2.b[ 0 ] = Data1.b[ 3 ];
  225.   Data2.b[ 1 ] = Data1.b[ 2 ];
  226.   Data2.b[ 2 ] = Data1.b[ 1 ];
  227.   Data2.b[ 3 ] = Data1.b[ 0 ];
  228.   return Data2.f;
  229. }
  230.  
  231. /*
  232. ====================
  233. KeepFloat
  234. ====================
  235. */
  236. float Endian::KeepFloat( const float fValue ) {
  237.   return fValue;
  238. }
  239.  
  240. /*
  241. ====================
  242. SwapDouble
  243. ====================
  244. */
  245. double Endian::SwapDouble( const double fValue ) {
  246.   union {
  247.     double f;
  248.     unsigned char b[ 8 ];
  249.   } Data1, Data2;
  250.  
  251.   Data1.f = fValue;
  252.   Data2.b[ 0 ] = Data1.b[ 7 ];
  253.   Data2.b[ 1 ] = Data1.b[ 6 ];
  254.   Data2.b[ 2 ] = Data1.b[ 5 ];
  255.   Data2.b[ 3 ] = Data1.b[ 4 ];
  256.   Data2.b[ 4 ] = Data1.b[ 3 ];
  257.   Data2.b[ 5 ] = Data1.b[ 2 ];
  258.   Data2.b[ 6 ] = Data1.b[ 1 ];
  259.   Data2.b[ 7 ] = Data1.b[ 0 ];
  260.   return Data2.f;
  261. }
  262.  
  263. /*
  264. ====================
  265. KeepDouble
  266. ====================
  267. */
  268. double Endian::KeepDouble( const double fValue ) {
  269.   return fValue;
  270. }
  271.  
  272. /*
  273. ====================
  274. SwapRevBytes
  275. ====================
  276. */
  277. void Endian::SwapRevBytes( void *pBase, const unsigned int nUnitSize, int nUnitCount ) {
  278.   register unsigned char *pLower, *pUpper;
  279.   pLower = ( unsigned char* )pBase;
  280.  
  281.   if( nUnitSize == 2 ) {
  282.     pUpper = pLower + 1;
  283.     while( nUnitCount-- ) {
  284.       *pLower ^= *pUpper;
  285.       *pUpper ^= *pLower;
  286.       *pLower ^= *pUpper;
  287.       pLower += 2;
  288.       pUpper += 2;
  289.     }
  290.     return;
  291.   }
  292.  
  293.   while( nUnitCount-- ) {
  294.     pUpper = pLower + nUnitSize - 1;
  295.     while( pLower < pUpper ) {
  296.       *pLower ^= *pUpper;
  297.       *pUpper ^= *pLower;
  298.       *pLower ^= *pUpper;
  299.       ++pLower;
  300.       --pUpper;
  301.     }
  302.     pLower += nUnitSize >> 1;
  303.   }
  304. }
  305.  
  306. /*
  307. ====================
  308. KeepRevBytes
  309. ====================
  310. */
  311. void Endian::KeepRevBytes( void *pBase, const unsigned int nUnitSize, int nUnitCount ) {
  312.   return;
  313. }
  314.  
Advertisement
Add Comment
Please, Sign In to add comment